use crate::types::Namespace;
use itertools::Itertools;
use std::collections::HashMap;
#[derive(Default)]
pub(crate) struct BridgeNameTracker {
next_cxx_bridge_name_for_prefix: HashMap<String, usize>,
}
impl BridgeNameTracker {
pub(crate) fn new() -> Self {
Self::default()
}
pub(crate) fn get_unique_cxx_bridge_name(
&mut self,
type_name: Option<&str>,
found_name: &str,
ns: &Namespace,
) -> String {
let count = self
.next_cxx_bridge_name_for_prefix
.entry(found_name.to_string())
.or_default();
if *count == 0 {
*count += 1;
return found_name.to_string();
}
let prefix = ns
.iter()
.cloned()
.chain(type_name.iter().map(|x| x.to_string()))
.chain(std::iter::once(found_name.to_string()))
.join("_");
let count = self
.next_cxx_bridge_name_for_prefix
.entry(prefix.clone())
.or_default();
if *count == 0 {
*count += 1;
prefix
} else {
let r = format!("{}_autocxx{}", prefix, count);
*count += 1;
r
}
}
}
#[cfg(test)]
mod tests {
use crate::types::Namespace;
use super::BridgeNameTracker;
#[test]
fn test() {
let mut bnt = BridgeNameTracker::new();
let ns_root = Namespace::new();
let ns_a = Namespace::from_user_input("A");
let ns_b = Namespace::from_user_input("B");
let ns_ab = Namespace::from_user_input("A::B");
assert_eq!(bnt.get_unique_cxx_bridge_name(None, "do", &ns_root), "do");
assert_eq!(
bnt.get_unique_cxx_bridge_name(None, "do", &ns_root),
"do_autocxx1"
);
assert_eq!(bnt.get_unique_cxx_bridge_name(None, "did", &ns_root), "did");
assert_eq!(
bnt.get_unique_cxx_bridge_name(Some("ty1"), "do", &ns_root),
"ty1_do"
);
assert_eq!(
bnt.get_unique_cxx_bridge_name(Some("ty1"), "do", &ns_root),
"ty1_do_autocxx1"
);
assert_eq!(
bnt.get_unique_cxx_bridge_name(Some("ty2"), "do", &ns_root),
"ty2_do"
);
assert_eq!(
bnt.get_unique_cxx_bridge_name(Some("ty"), "do", &ns_a),
"A_ty_do"
);
assert_eq!(
bnt.get_unique_cxx_bridge_name(Some("ty"), "do", &ns_b),
"B_ty_do"
);
assert_eq!(
bnt.get_unique_cxx_bridge_name(Some("ty"), "do", &ns_ab),
"A_B_ty_do"
);
}
}