blob: 0c21d99f12111d8bd2cc9e07308074797d431b28 [file] [log] [blame]
Chih-Hung Hsieh92ff6052020-06-10 20:18:39 -07001use crate::rust;
2use crate::rust_name::RustIdent;
3use crate::strx;
4
5// Copy-pasted from libsyntax.
6fn ident_start(c: char) -> bool {
7 (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'
8}
9
10// Copy-pasted from libsyntax.
11fn ident_continue(c: char) -> bool {
12 (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'
13}
14
15pub(crate) fn proto_path_to_rust_mod(path: &str) -> RustIdent {
16 let without_dir = strx::remove_to(path, '/');
17 let without_suffix = strx::remove_suffix(without_dir, ".proto");
18
19 let name = without_suffix
20 .chars()
21 .enumerate()
22 .map(|(i, c)| {
23 let valid = if i == 0 {
24 ident_start(c)
25 } else {
26 ident_continue(c)
27 };
28 if valid {
29 c
30 } else {
31 '_'
32 }
33 })
34 .collect::<String>();
35
36 let name = if rust::is_rust_keyword(&name) {
37 format!("{}_pb", name)
38 } else {
39 name
40 };
41 RustIdent::from(name)
42}
43
44#[cfg(test)]
45mod test {
46
47 use super::proto_path_to_rust_mod;
48 use crate::rust_name::RustIdent;
49
50 #[test]
51 fn test_mod_path_proto_ext() {
52 assert_eq!(
53 RustIdent::from("proto"),
54 proto_path_to_rust_mod("proto.proto")
55 );
56 }
57
58 #[test]
59 fn test_mod_path_unknown_ext() {
60 assert_eq!(
61 RustIdent::from("proto_proto3"),
62 proto_path_to_rust_mod("proto.proto3")
63 );
64 }
65
66 #[test]
67 fn test_mod_path_empty_ext() {
68 assert_eq!(RustIdent::from("proto"), proto_path_to_rust_mod("proto"));
69 }
70}