1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! This tool generates Rust code with assigned number tables from the equivalent Python.
16 
17 use pyo3::{
18     intern,
19     types::{PyDict, PyModule},
20     PyResult, Python,
21 };
22 use std::{collections, env, fs, path};
23 
main() -> anyhow::Result<()>24 fn main() -> anyhow::Result<()> {
25     pyo3::prepare_freethreaded_python();
26     let mut dir = path::Path::new(&env::var("CARGO_MANIFEST_DIR")?).to_path_buf();
27     dir.push("src/wrapper/assigned_numbers");
28 
29     company_ids(&dir)?;
30 
31     Ok(())
32 }
33 
company_ids(base_dir: &path::Path) -> anyhow::Result<()>34 fn company_ids(base_dir: &path::Path) -> anyhow::Result<()> {
35     let mut sorted_ids = load_company_ids()?.into_iter().collect::<Vec<_>>();
36     sorted_ids.sort_by_key(|(id, _name)| *id);
37 
38     let mut contents = String::new();
39     contents.push_str(LICENSE_HEADER);
40     contents.push_str("\n\n");
41     contents.push_str(
42         "// auto-generated by gen_assigned_numbers, do not edit
43 
44 use crate::wrapper::core::Uuid16;
45 use lazy_static::lazy_static;
46 use std::collections;
47 
48 lazy_static! {
49     /// Assigned company IDs
50     pub static ref COMPANY_IDS: collections::HashMap<Uuid16, &'static str> = [
51 ",
52     );
53 
54     for (id, name) in sorted_ids {
55         contents.push_str(&format!("        ({id}_u16, r#\"{name}\"#),\n"))
56     }
57 
58     contents.push_str(
59         "    ]
60     .into_iter()
61     .map(|(id, name)| (Uuid16::from_be_bytes(id.to_be_bytes()), name))
62     .collect();
63 }
64 ",
65     );
66 
67     let mut company_ids = base_dir.to_path_buf();
68     company_ids.push("company_ids.rs");
69     fs::write(&company_ids, contents)?;
70 
71     Ok(())
72 }
73 
load_company_ids() -> PyResult<collections::HashMap<u16, String>>74 fn load_company_ids() -> PyResult<collections::HashMap<u16, String>> {
75     Python::with_gil(|py| {
76         PyModule::import(py, intern!(py, "bumble.company_ids"))?
77             .getattr(intern!(py, "COMPANY_IDENTIFIERS"))?
78             .downcast::<PyDict>()?
79             .into_iter()
80             .map(|(k, v)| Ok((k.extract::<u16>()?, v.str()?.to_str()?.to_string())))
81             .collect::<PyResult<collections::HashMap<_, _>>>()
82     })
83 }
84 
85 const LICENSE_HEADER: &str = r#"// Copyright 2023 Google LLC
86 //
87 // Licensed under the Apache License, Version 2.0 (the "License");
88 // you may not use this file except in compliance with the License.
89 // You may obtain a copy of the License at
90 //
91 //     http://www.apache.org/licenses/LICENSE-2.0
92 //
93 // Unless required by applicable law or agreed to in writing, software
94 // distributed under the License is distributed on an "AS IS" BASIS,
95 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
96 // See the License for the specific language governing permissions and
97 // limitations under the License."#;
98