cxx_build/syntax/
symbol.rs1use crate::syntax::namespace::Namespace;
2use crate::syntax::{ForeignName, Pair};
3use proc_macro2::{Ident, TokenStream};
4use quote::ToTokens;
5use std::fmt::{self, Display, Write};
6
7pub(crate) struct Symbol(String);
10
11impl Display for Symbol {
12 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
13 Display::fmt(&self.0, formatter)
14 }
15}
16
17impl ToTokens for Symbol {
18 fn to_tokens(&self, tokens: &mut TokenStream) {
19 ToTokens::to_tokens(&self.0, tokens);
20 }
21}
22
23impl Symbol {
24 fn push(&mut self, segment: &dyn Display) {
25 let len_before = self.0.len();
26 if !self.0.is_empty() {
27 self.0.push('$');
28 }
29 self.0.write_fmt(format_args!("{0}", segment)format_args!("{}", segment)).unwrap();
30 if !(self.0.len() > len_before) {
::core::panicking::panic("assertion failed: self.0.len() > len_before")
};assert!(self.0.len() > len_before);
31 }
32
33 pub(crate) fn from_idents<'a>(it: impl Iterator<Item = &'a dyn Segment>) -> Self {
34 let mut symbol = Symbol(String::new());
35 for segment in it {
36 segment.write(&mut symbol);
37 }
38 if !!symbol.0.is_empty() {
::core::panicking::panic("assertion failed: !symbol.0.is_empty()")
};assert!(!symbol.0.is_empty());
39 symbol
40 }
41
42 #[cfg_attr(proc_macro, expect(dead_code))]
43 pub(crate) fn contains(&self, ch: char) -> bool {
44 self.0.contains(ch)
45 }
46}
47
48pub(crate) trait Segment {
49 fn write(&self, symbol: &mut Symbol);
50}
51
52impl Segment for str {
53 fn write(&self, symbol: &mut Symbol) {
54 symbol.push(&self);
55 }
56}
57
58impl Segment for usize {
59 fn write(&self, symbol: &mut Symbol) {
60 symbol.push(&self);
61 }
62}
63
64impl Segment for Ident {
65 fn write(&self, symbol: &mut Symbol) {
66 symbol.push(&self);
67 }
68}
69
70impl Segment for Symbol {
71 fn write(&self, symbol: &mut Symbol) {
72 symbol.push(&self);
73 }
74}
75
76impl Segment for Namespace {
77 fn write(&self, symbol: &mut Symbol) {
78 for segment in self {
79 symbol.push(segment);
80 }
81 }
82}
83
84impl Segment for Pair {
85 fn write(&self, symbol: &mut Symbol) {
86 self.namespace.write(symbol);
87 self.cxx.write(symbol);
88 }
89}
90
91impl Segment for ForeignName {
92 fn write(&self, symbol: &mut Symbol) {
93 self.to_string().write(symbol);
96 }
97}
98
99impl<T> Segment for &'_ T
100where
101 T: ?Sized + Segment + Display,
102{
103 fn write(&self, symbol: &mut Symbol) {
104 (**self).write(symbol);
105 }
106}
107
108pub(crate) fn join(segments: &[&dyn Segment]) -> Symbol {
109 let mut symbol = Symbol(String::new());
110 for segment in segments {
111 segment.write(&mut symbol);
112 }
113 if !!symbol.0.is_empty() {
::core::panicking::panic("assertion failed: !symbol.0.is_empty()")
};assert!(!symbol.0.is_empty());
114 symbol
115}