• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::gen::inside::protobuf_crate_path;
2 use crate::gen::rust::ident::RustIdent;
3 use crate::gen::rust::path::RustPath;
4 use crate::gen::strx;
5 use crate::gen::well_known_types::WELL_KNOWN_TYPES_PROTO_FILE_FULL_NAMES;
6 use crate::Customize;
7 
8 // Copy-pasted from libsyntax.
ident_start(c: char) -> bool9 fn ident_start(c: char) -> bool {
10     (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'
11 }
12 
13 // Copy-pasted from libsyntax.
ident_continue(c: char) -> bool14 fn ident_continue(c: char) -> bool {
15     (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'
16 }
17 
proto_path_to_rust_mod(path: &str) -> RustIdent18 pub(crate) fn proto_path_to_rust_mod(path: &str) -> RustIdent {
19     let without_dir = strx::remove_to(path, std::path::is_separator);
20     let without_suffix = strx::remove_suffix(without_dir, ".proto");
21 
22     let name = without_suffix
23         .chars()
24         .enumerate()
25         .map(|(i, c)| {
26             let valid = if i == 0 {
27                 ident_start(c)
28             } else {
29                 ident_continue(c)
30             };
31             if valid {
32                 c
33             } else {
34                 '_'
35             }
36         })
37         .collect::<String>();
38 
39     RustIdent::new(&name)
40 }
41 
42 /// Used in protobuf-codegen-identical-test
proto_name_to_rs(proto_file_path: &str) -> String43 pub fn proto_name_to_rs(proto_file_path: &str) -> String {
44     format!("{}.rs", proto_path_to_rust_mod(proto_file_path))
45 }
46 
proto_path_to_fn_file_descriptor( proto_path: &str, customize: &Customize, ) -> RustPath47 pub(crate) fn proto_path_to_fn_file_descriptor(
48     proto_path: &str,
49     customize: &Customize,
50 ) -> RustPath {
51     let protobuf_crate = protobuf_crate_path(customize);
52     match proto_path {
53         "rustproto.proto" => protobuf_crate.append("rustproto::file_descriptor".into()),
54         "google/protobuf/descriptor.proto" => {
55             protobuf_crate.append("descriptor::file_descriptor".into())
56         }
57         s if WELL_KNOWN_TYPES_PROTO_FILE_FULL_NAMES.contains(&s) => protobuf_crate
58             .append_ident("well_known_types".into())
59             .append_ident(proto_path_to_rust_mod(s))
60             .append_ident("file_descriptor".into()),
61         s => RustPath::super_path()
62             .append_ident(proto_path_to_rust_mod(s))
63             .append_ident("file_descriptor".into()),
64     }
65 }
66 
67 #[cfg(test)]
68 mod test {
69     use super::proto_path_to_rust_mod;
70     use crate::gen::rust::ident::RustIdent;
71 
72     #[test]
test_mod_path_proto_ext()73     fn test_mod_path_proto_ext() {
74         assert_eq!(
75             RustIdent::from("proto"),
76             proto_path_to_rust_mod("proto.proto")
77         );
78     }
79 
80     #[test]
test_mod_path_unknown_ext()81     fn test_mod_path_unknown_ext() {
82         assert_eq!(
83             RustIdent::from("proto_proto3"),
84             proto_path_to_rust_mod("proto.proto3")
85         );
86     }
87 
88     #[test]
test_mod_path_empty_ext()89     fn test_mod_path_empty_ext() {
90         assert_eq!(RustIdent::from("proto"), proto_path_to_rust_mod("proto"));
91     }
92 
93     #[test]
test_mod_path_dir()94     fn test_mod_path_dir() {
95         assert_eq!(
96             RustIdent::from("baz"),
97             proto_path_to_rust_mod("foo/bar/baz.proto"),
98         )
99     }
100 
101     #[cfg(target_os = "windows")]
102     #[test]
test_mod_path_dir_backslashes()103     fn test_mod_path_dir_backslashes() {
104         assert_eq!(
105             RustIdent::from("baz"),
106             proto_path_to_rust_mod("foo\\bar\\baz.proto"),
107         )
108     }
109 }
110