Avoid using common substrings as encodings. (#1370)

This tweaks the encoding used by the `import` macro to avoid using encodings that could be common substrings in target names.

E.g., `foo_c_api` is a perfectly reasonable target name, but since it contains the substring `_c_`, it must be mangled by the macro. It would be better if the encoding avoided such cases.
diff --git a/rust/private/utils.bzl b/rust/private/utils.bzl
index 431502a..0ad8de9 100644
--- a/rust/private/utils.bzl
+++ b/rust/private/utils.bzl
@@ -463,37 +463,37 @@
 # the second element is an encoding of that char suitable for use in a crate
 # name.
 _encodings = (
-    (":", "c"),
-    ("!", "bang"),
-    ("%", "perc"),
-    ("@", "at"),
+    (":", "x"),
+    ("!", "excl"),
+    ("%", "prc"),
+    ("@", "ao"),
     ("^", "caret"),
     ("`", "bt"),
     (" ", "sp"),
     ("\"", "dq"),
-    ("#", "hash"),
-    ("$", "dollar"),
+    ("#", "octo"),
+    ("$", "dllr"),
     ("&", "amp"),
     ("'", "sq"),
     ("(", "lp"),
     (")", "rp"),
-    ("*", "star"),
+    ("*", "astr"),
     ("-", "d"),
-    ("+", "plus"),
-    (",", "comma"),
-    (";", "semi"),
-    ("<", "langle"),
+    ("+", "pl"),
+    (",", "cm"),
+    (";", "sm"),
+    ("<", "la"),
     ("=", "eq"),
-    (">", "rangle"),
+    (">", "ra"),
     ("?", "qm"),
-    ("[", "lbrack"),
-    ("]", "rbrack"),
-    ("{", "lbrace"),
-    ("|", "pipe"),
-    ("}", "rbrace"),
-    ("~", "tilde"),
-    ("/", "s"),
-    (".", "dot"),
+    ("[", "lbk"),
+    ("]", "rbk"),
+    ("{", "lbe"),
+    ("|", "pp"),
+    ("}", "rbe"),
+    ("~", "td"),
+    ("/", "y"),
+    (".", "pd"),
 )
 
 # For each of the above encodings, we generate two substitution rules: one that
diff --git a/test/unit/utils/utils_test.bzl b/test/unit/utils/utils_test.bzl
index e99bc35..7e995a1 100644
--- a/test/unit/utils/utils_test.bzl
+++ b/test/unit/utils/utils_test.bzl
@@ -11,47 +11,47 @@
     # Typical cases.
     asserts.equals(
         env,
-        "x_s_y_c_z",
+        "x_y_y_x_z",
         encode_label_as_crate_name("x/y", "z"),
     )
     asserts.equals(
         env,
-        "some_s_package_c_target",
+        "some_y_package_x_target",
         encode_label_as_crate_name("some/package", "target"),
     )
 
     # Target name includes a character illegal in crate names.
     asserts.equals(
         env,
-        "some_s_package_c_foo_s_target",
+        "some_y_package_x_foo_y_target",
         encode_label_as_crate_name("some/package", "foo/target"),
     )
 
     # Package/target includes some of the encodings.
     asserts.equals(
         env,
-        "some_zs__s_package_c_target_zdot_foo",
-        encode_label_as_crate_name("some_s_/package", "target_dot_foo"),
+        "some_zy__y_package_x_target_zpd_foo",
+        encode_label_as_crate_name("some_y_/package", "target_pd_foo"),
     )
 
     # Some pathological cases: test that round-tripping the encoding works as
     # expected.
 
     # Label includes a quoted encoding.
-    package = "_zdot_"
+    package = "_zpd_"
     target = "target"
-    asserts.equals(env, "_zz_dot__c_target", encode_label_as_crate_name(package, target))
+    asserts.equals(env, "_zz_pd__x_target", encode_label_as_crate_name(package, target))
     asserts.equals(env, package + ":" + target, decode_crate_name_as_label_for_testing(encode_label_as_crate_name(package, target)))
 
-    package = "x_s_y"
+    package = "x_y_y"
     target = "z"
-    asserts.equals(env, "x_zs_y_c_z", encode_label_as_crate_name(package, target))
+    asserts.equals(env, "x_zy_y_x_z", encode_label_as_crate_name(package, target))
     asserts.equals(env, package + ":" + target, decode_crate_name_as_label_for_testing(encode_label_as_crate_name(package, target)))
 
     # Package is identical to a valid encoding already.
-    package = "_zz_dot__c_target"
+    package = "_zz_pd__x_target"
     target = "target"
-    asserts.equals(env, "_zz_z_zdot__zc_target_c_target", encode_label_as_crate_name(package, target))
+    asserts.equals(env, "_zz_z_zpd__zx_target_x_target", encode_label_as_crate_name(package, target))
     asserts.equals(env, package + ":" + target, decode_crate_name_as_label_for_testing(encode_label_as_crate_name(package, target)))
     return unittest.end(env)
 
@@ -70,8 +70,8 @@
 
 def _encode_raw_string_test_impl(ctx):
     env = unittest.begin(ctx)
-    asserts.equals(env, encode_raw_string_for_testing("some_project:utils"), "some_project_c_utils")
-    asserts.equals(env, encode_raw_string_for_testing("_zdot_"), "_zz_dot_")
+    asserts.equals(env, encode_raw_string_for_testing("some_project:utils"), "some_project_x_utils")
+    asserts.equals(env, encode_raw_string_for_testing("_zpd_"), "_zz_pd_")
 
     # No surprises in the application of the substitutions, everything is
     # encoded as expected.
@@ -83,8 +83,8 @@
 #
 def _decode_test_impl(ctx):
     env = unittest.begin(ctx)
-    asserts.equals(env, decode_crate_name_as_label_for_testing("some_project_c_utils"), "some_project:utils")
-    asserts.equals(env, decode_crate_name_as_label_for_testing("_zz_dot_"), "_zdot_")
+    asserts.equals(env, decode_crate_name_as_label_for_testing("some_project_x_utils"), "some_project:utils")
+    asserts.equals(env, decode_crate_name_as_label_for_testing("_zz_pd_"), "_zpd_")
 
     # No surprises in the application of the substitutions, everything is
     # decoded as expected.
diff --git a/util/import/import_internal.rs b/util/import/import_internal.rs
index e520756..8b6e061 100644
--- a/util/import/import_internal.rs
+++ b/util/import/import_internal.rs
@@ -77,37 +77,37 @@
     // //rust/private/utils.bzl exactly.
     static ref ENCODINGS: Vec<(&'static str, &'static str)> =
             vec![
-                    (":", "c"),
-                    ("!", "bang"),
-                    ("%", "perc"),
-                    ("@", "at"),
+                    (":", "x"),
+                    ("!", "excl"),
+                    ("%", "prc"),
+                    ("@", "ao"),
                     ("^", "caret"),
                     ("`", "bt"),
                     (" ", "sp"),
                     ("\"", "dq"),
-                    ("#", "hash"),
-                    ("$", "dollar"),
+                    ("#", "octo"),
+                    ("$", "dllr"),
                     ("&", "amp"),
                     ("'", "sq"),
                     ("(", "lp"),
                     (")", "rp"),
-                    ("*", "star"),
+                    ("*", "astr"),
                     ("-", "d"),
-                    ("+", "plus"),
-                    (",", "comma"),
-                    (";", "semi"),
-                    ("<", "langle"),
+                    ("+", "pl"),
+                    (",", "cm"),
+                    (";", "sm"),
+                    ("<", "la"),
                     ("=", "eq"),
-                    (">", "rangle"),
+                    (">", "ra"),
                     ("?", "qm"),
-                    ("[", "lbrack"),
-                    ("]", "rbrack"),
-                    ("{", "lbrace"),
-                    ("|", "pipe"),
-                    ("}", "rbrace"),
-                    ("~", "tilde"),
-                    ("/", "s"),
-                    (".", "dot"),
+                    ("[", "lbk"),
+                    ("]", "rbk"),
+                    ("{", "lbe"),
+                    ("|", "pp"),
+                    ("}", "rbe"),
+                    ("~", "td"),
+                    ("/", "y"),
+                    (".", "pd"),
             ];
 
     // Transformations are stored as "(unencoded, encoded)" tuples.
@@ -311,42 +311,42 @@
         let expanded = expand_imports(parse_quote! { "//some_project:utils"; }, &mode)?;
         assert_eq!(
             expanded.to_string(),
-            "extern crate some_project_c_utils as utils ;"
+            "extern crate some_project_x_utils as utils ;"
         );
 
         // Package and a target, with a no-op alias.
         let expanded = expand_imports(parse_quote! { "//some_project:utils" as utils; }, &mode)?;
         assert_eq!(
             expanded.to_string(),
-            "extern crate some_project_c_utils as utils ;"
+            "extern crate some_project_x_utils as utils ;"
         );
 
         // Package and a target, with an alias.
         let expanded = expand_imports(parse_quote! { "//some_project:utils" as my_utils; }, &mode)?;
         assert_eq!(
             expanded.to_string(),
-            "extern crate some_project_c_utils as my_utils ;"
+            "extern crate some_project_x_utils as my_utils ;"
         );
 
         // Package and an implicit target.
         let expanded = expand_imports(parse_quote! { "//some_project/utils"; }, &mode)?;
         assert_eq!(
             expanded.to_string(),
-            "extern crate some_project_s_utils_c_utils as utils ;"
+            "extern crate some_project_y_utils_x_utils as utils ;"
         );
 
         // Package and an implicit target, with a no-op alias.
         let expanded = expand_imports(parse_quote! { "//some_project/utils" as utils; }, &mode)?;
         assert_eq!(
             expanded.to_string(),
-            "extern crate some_project_s_utils_c_utils as utils ;"
+            "extern crate some_project_y_utils_x_utils as utils ;"
         );
 
         // Package and an implicit target, with an alias.
         let expanded = expand_imports(parse_quote! { "//some_project/utils" as my_utils; }, &mode)?;
         assert_eq!(
             expanded.to_string(),
-            "extern crate some_project_s_utils_c_utils as my_utils ;"
+            "extern crate some_project_y_utils_x_utils as my_utils ;"
         );
 
         // A third-party target.
@@ -375,14 +375,14 @@
         )?;
         assert_eq!(
             expanded.to_string(),
-            "extern crate some_project_c_utils as utils ; extern crate serde ;"
+            "extern crate some_project_x_utils as utils ; extern crate serde ;"
         );
 
         // Problematic target name.
         let expanded = expand_imports(parse_quote! { "//some_project:thing-types"; }, &mode)?;
         assert_eq!(
             expanded.to_string(),
-            "extern crate some_project_c_thing_d_types as thing_d_types ;"
+            "extern crate some_project_x_thing_d_types as thing_d_types ;"
         );
 
         // Problematic target name with alias.
@@ -392,14 +392,14 @@
         )?;
         assert_eq!(
             expanded.to_string(),
-            "extern crate some_project_c_thing_d_types as types ;"
+            "extern crate some_project_x_thing_d_types as types ;"
         );
 
         // Problematic package name.
         let expanded = expand_imports(parse_quote! { "//some_project-prototype:utils"; }, &mode)?;
         assert_eq!(
             expanded.to_string(),
-            "extern crate some_project_d_prototype_c_utils as utils ;"
+            "extern crate some_project_d_prototype_x_utils as utils ;"
         );
 
         // Problematic package and target names.
@@ -409,7 +409,7 @@
         )?;
         assert_eq!(
             expanded.to_string(),
-            "extern crate some_project_d_prototype_c_thing_d_types as thing_d_types ;"
+            "extern crate some_project_d_prototype_x_thing_d_types as thing_d_types ;"
         );
 
         Ok(())
@@ -541,8 +541,8 @@
 
     #[test]
     fn test_encode() -> Result<()> {
-        assert_eq!(encode("some_project:utils"), "some_project_c_utils");
-        assert_eq!(&encode("_zdot_"), "_zz_dot_");
+        assert_eq!(encode("some_project:utils"), "some_project_x_utils");
+        assert_eq!(&encode("_zpd_"), "_zz_pd_");
 
         // All the encodings should be what we expect.
         for (orig, encoded) in SUBSTITUTIONS.0.iter().zip(SUBSTITUTIONS.1.iter()) {
@@ -554,8 +554,8 @@
 
     #[test]
     fn test_decode() -> Result<()> {
-        assert_eq!(decode("some_project_c_utils"), "some_project:utils");
-        assert_eq!(decode("_zz_dot_"), "_zdot_");
+        assert_eq!(decode("some_project_x_utils"), "some_project:utils");
+        assert_eq!(decode("_zz_pd_"), "_zpd_");
 
         // All the decodings should be what we expect.
         for (orig, encoded) in SUBSTITUTIONS.0.iter().zip(SUBSTITUTIONS.1.iter()) {