11use core:: {
22 fmt:: Debug ,
3- ops:: { Deref , DerefMut } , slice:: IterMut ,
3+ ops:: { Deref , DerefMut } ,
4+ slice:: IterMut ,
45} ;
56
6- use alloc:: vec:: Vec ;
7+ use alloc:: { string :: String , vec:: Vec } ;
78
8- use crate :: { Context , Node , Property } ;
9+ use crate :: { Context , Node , Property , ctx } ;
910
1011#[ derive( Clone , Debug ) ]
1112pub enum NodeRef < ' a > {
@@ -16,6 +17,25 @@ impl<'a> NodeRef<'a> {
1617 pub fn new ( node : & ' a Node , ctx : Context < ' a > ) -> Self {
1718 Self :: Gerneric ( NodeRefGen { node, ctx } )
1819 }
20+
21+ fn op ( & ' a self ) -> RefOp < ' a > {
22+ RefOp {
23+ ctx : & self . ctx ,
24+ node : self . node ,
25+ }
26+ }
27+
28+ pub fn path ( & self ) -> String {
29+ self . op ( ) . path ( )
30+ }
31+
32+ pub fn path_eq ( & self , path : & str ) -> bool {
33+ self . op ( ) . ref_path_eq ( path)
34+ }
35+
36+ pub fn path_eq_fuzzy ( & self , path : & str ) -> bool {
37+ self . op ( ) . ref_path_eq_fuzzy ( path)
38+ }
1939}
2040
2141#[ derive( Clone ) ]
@@ -67,6 +87,25 @@ impl<'a> NodeMut<'a> {
6787 pub fn new ( node : & ' a mut Node , ctx : Context < ' a > ) -> Self {
6888 Self :: Gerneric ( NodeMutGen { node, ctx } )
6989 }
90+
91+ fn op ( & ' a self ) -> RefOp < ' a > {
92+ RefOp {
93+ ctx : & self . ctx ,
94+ node : self . node ,
95+ }
96+ }
97+
98+ pub fn path ( & self ) -> String {
99+ self . op ( ) . path ( )
100+ }
101+
102+ pub fn path_eq ( & self , path : & str ) -> bool {
103+ self . op ( ) . ref_path_eq ( path)
104+ }
105+
106+ pub fn path_eq_fuzzy ( & self , path : & str ) -> bool {
107+ self . op ( ) . ref_path_eq_fuzzy ( path)
108+ }
70109}
71110
72111impl < ' a > Deref for NodeMut < ' a > {
@@ -143,3 +182,60 @@ impl Debug for NodeRefGen<'_> {
143182 write ! ( f, "NodeRefGen {{ name: {} }}" , self . node. name( ) )
144183 }
145184}
185+
186+ struct RefOp < ' a > {
187+ ctx : & ' a Context < ' a > ,
188+ node : & ' a Node ,
189+ }
190+
191+ impl < ' a > RefOp < ' a > {
192+ fn path ( & self ) -> String {
193+ self . ctx . current_path ( ) + "/" + self . node . name ( )
194+ }
195+
196+ fn ref_path_eq ( & self , path : & str ) -> bool {
197+ self . path ( ) == path
198+ }
199+
200+ fn ref_path_eq_fuzzy ( & self , path : & str ) -> bool {
201+ let mut want = path. trim_matches ( '/' ) . split ( "/" ) ;
202+ let got_path = self . path ( ) ;
203+ let mut got = got_path. trim_matches ( '/' ) . split ( "/" ) ;
204+ let got_count = got. clone ( ) . count ( ) ;
205+ let mut current = 0 ;
206+
207+ loop {
208+ let w = want. next ( ) ;
209+ let g = got. next ( ) ;
210+ let is_last = current + 1 == got_count;
211+
212+ match ( w, g) {
213+ ( Some ( w) , Some ( g) ) => {
214+ if w != g && !is_last {
215+ return false ;
216+ }
217+
218+ let name = g. split ( '@' ) . next ( ) . unwrap_or ( g) ;
219+ let addr = g. split ( '@' ) . nth ( 1 ) ;
220+
221+ let want_name = w. split ( '@' ) . next ( ) . unwrap_or ( w) ;
222+ let want_addr = w. split ( '@' ) . nth ( 1 ) ;
223+
224+ let res = match ( addr, want_addr) {
225+ ( Some ( a) , Some ( wa) ) => name == want_name && a == wa,
226+ ( Some ( _) , None ) => name == want_name,
227+ ( None , Some ( _) ) => false ,
228+ ( None , None ) => name == want_name,
229+ } ;
230+ if !res {
231+ return false ;
232+ }
233+ }
234+ ( None , _) => break ,
235+ _ => return false ,
236+ }
237+ current += 1 ;
238+ }
239+ true
240+ }
241+ }
0 commit comments