syn_solidity/ident/
path.rs1use crate::{SolIdent, Spanned};
2use proc_macro2::{Ident, Span};
3use std::{
4 fmt,
5 ops::{Deref, DerefMut},
6};
7use syn::{
8 ext::IdentExt,
9 parse::{Parse, ParseStream},
10 punctuated::Punctuated,
11 Result, Token,
12};
13
14#[macro_export]
16macro_rules! sol_path {
17 () => { $crate::SolPath::new() };
18
19 ($($e:expr),+) => {{
20 let mut path = $crate::SolPath::new();
21 $(path.push($crate::SolIdent::from($e));)+
22 path
23 }};
24}
25
26#[derive(Clone, PartialEq, Eq, Hash)]
30pub struct SolPath(Punctuated<SolIdent, Token![.]>);
31
32impl Deref for SolPath {
33 type Target = Punctuated<SolIdent, Token![.]>;
34
35 fn deref(&self) -> &Self::Target {
36 &self.0
37 }
38}
39
40impl DerefMut for SolPath {
41 fn deref_mut(&mut self) -> &mut Self::Target {
42 &mut self.0
43 }
44}
45
46impl fmt::Display for SolPath {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 for (i, ident) in self.0.iter().enumerate() {
49 if i > 0 {
50 f.write_str(".")?;
51 }
52 ident.fmt(f)?;
53 }
54 Ok(())
55 }
56}
57
58impl fmt::Debug for SolPath {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 f.debug_list().entries(&self.0).finish()
61 }
62}
63
64impl FromIterator<SolIdent> for SolPath {
65 fn from_iter<T: IntoIterator<Item = SolIdent>>(iter: T) -> Self {
66 Self(iter.into_iter().collect())
67 }
68}
69
70impl Parse for SolPath {
71 fn parse(input: ParseStream<'_>) -> Result<Self> {
72 let mut segments = Punctuated::new();
74 loop {
75 if !input.peek(Ident::peek_any) {
76 break;
77 }
78 segments.push_value(input.parse()?);
79 if !input.peek(Token![.]) {
80 break;
81 }
82 segments.push_punct(input.parse()?);
83 }
84
85 if segments.is_empty() {
86 Err(input.parse::<SolIdent>().unwrap_err())
87 } else if segments.trailing_punct() {
88 Err(input.error("expected path segment after `.`"))
89 } else {
90 Ok(Self(segments))
91 }
92 }
93}
94
95impl Spanned for SolPath {
96 fn span(&self) -> Span {
97 self.0.span()
98 }
99
100 fn set_span(&mut self, span: Span) {
101 self.0.set_span(span);
102 }
103}
104
105impl Default for SolPath {
106 fn default() -> Self {
107 Self::new()
108 }
109}
110
111impl SolPath {
112 pub const fn new() -> Self {
113 Self(Punctuated::new())
114 }
115
116 pub fn first(&self) -> &SolIdent {
117 self.0.first().unwrap()
118 }
119
120 pub fn first_mut(&mut self) -> &mut SolIdent {
121 self.0.first_mut().unwrap()
122 }
123
124 pub fn last(&self) -> &SolIdent {
125 self.0.last().unwrap()
126 }
127
128 pub fn last_mut(&mut self) -> &mut SolIdent {
129 self.0.last_mut().unwrap()
130 }
131}