@@ -100,38 +100,45 @@ pub fn is_match(regex: &str, text: &str) -> Result<bool, parse::Error> {
100
100
/// documentation.
101
101
#[ deriving( Clone ) ]
102
102
#[ allow( visible_private_types) ]
103
- pub struct Regex {
104
- /// The representation of `Regex` is exported to support the `regex!`
105
- /// syntax extension. Do not rely on it.
106
- ///
107
- /// See the comments for the `program` module in `lib.rs` for a more
108
- /// detailed explanation for what `regex!` requires.
103
+ pub enum Regex {
104
+ // The representation of `Regex` is exported to support the `regex!`
105
+ // syntax extension. Do not rely on it.
106
+ //
107
+ // See the comments for the `program` module in `lib.rs` for a more
108
+ // detailed explanation for what `regex!` requires.
109
109
#[ doc( hidden) ]
110
- pub original : String ,
110
+ Dynamic ( Dynamic ) ,
111
111
#[ doc( hidden) ]
112
- pub names : Vec < Option < String > > ,
112
+ Native ( Native ) ,
113
+ }
114
+
115
+ #[ deriving( Clone ) ]
116
+ #[ doc( hidden) ]
117
+ pub struct Dynamic {
118
+ original : String ,
119
+ names : Vec < Option < String > > ,
113
120
#[ doc( hidden) ]
114
- pub p : MaybeNative ,
121
+ pub prog : Program
115
122
}
116
123
117
- impl fmt:: Show for Regex {
118
- /// Shows the original regular expression.
119
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
120
- write ! ( f, "{}" , self . original)
121
- }
124
+ #[ doc( hidden) ]
125
+ pub struct Native {
126
+ #[ doc( hidden) ]
127
+ pub original : & ' static str ,
128
+ #[ doc( hidden) ]
129
+ pub names : & ' static [ Option < & ' static str > ] ,
130
+ #[ doc( hidden) ]
131
+ pub prog : fn ( MatchKind , & str , uint , uint ) -> Vec < Option < uint > >
122
132
}
123
133
124
- pub enum MaybeNative {
125
- Dynamic ( Program ) ,
126
- Native ( fn ( MatchKind , & str , uint , uint ) -> Vec < Option < uint > > ) ,
134
+ impl Clone for Native {
135
+ fn clone ( & self ) -> Native { * self }
127
136
}
128
137
129
- impl Clone for MaybeNative {
130
- fn clone ( & self ) -> MaybeNative {
131
- match * self {
132
- Dynamic ( ref p) => Dynamic ( p. clone ( ) ) ,
133
- Native ( fp) => Native ( fp) ,
134
- }
138
+ impl fmt:: Show for Regex {
139
+ /// Shows the original regular expression.
140
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
141
+ write ! ( f, "{}" , self . as_str( ) )
135
142
}
136
143
}
137
144
@@ -146,10 +153,11 @@ impl Regex {
146
153
pub fn new ( re : & str ) -> Result < Regex , parse:: Error > {
147
154
let ast = try!( parse:: parse ( re) ) ;
148
155
let ( prog, names) = Program :: new ( ast) ;
149
- Ok ( Regex {
156
+ Ok ( Dynamic ( Dynamic {
150
157
original : re. to_strbuf ( ) ,
151
- names : names, p : Dynamic ( prog) ,
152
- } )
158
+ names : names,
159
+ prog : prog,
160
+ } ) )
153
161
}
154
162
155
163
/// Returns true if and only if the regex matches the string given.
@@ -495,6 +503,46 @@ impl Regex {
495
503
}
496
504
new. append ( text. slice ( last_match, text. len ( ) ) )
497
505
}
506
+
507
+ /// Returns the original string of this regex.
508
+ pub fn as_str < ' a > ( & ' a self ) -> & ' a str {
509
+ match * self {
510
+ Dynamic ( Dynamic { ref original, .. } ) => original. as_slice ( ) ,
511
+ Native ( Native { ref original, .. } ) => original. as_slice ( ) ,
512
+ }
513
+ }
514
+
515
+ #[ doc( hidden) ]
516
+ #[ allow( visible_private_types) ]
517
+ #[ experimental]
518
+ pub fn names_iter < ' a > ( & ' a self ) -> NamesIter < ' a > {
519
+ match * self {
520
+ Native ( ref n) => NamesIterNative ( n. names . iter ( ) ) ,
521
+ Dynamic ( ref d) => NamesIterDynamic ( d. names . iter ( ) )
522
+ }
523
+ }
524
+
525
+ fn names_len ( & self ) -> uint {
526
+ match * self {
527
+ Native ( ref n) => n. names . len ( ) ,
528
+ Dynamic ( ref d) => d. names . len ( )
529
+ }
530
+ }
531
+
532
+ }
533
+
534
+ enum NamesIter < ' a > {
535
+ NamesIterNative ( :: std:: slice:: Items < ' a , Option < & ' static str > > ) ,
536
+ NamesIterDynamic ( :: std:: slice:: Items < ' a , Option < String > > )
537
+ }
538
+
539
+ impl < ' a > Iterator < Option < String > > for NamesIter < ' a > {
540
+ fn next ( & mut self ) -> Option < Option < String > > {
541
+ match * self {
542
+ NamesIterNative ( ref mut i) => i. next ( ) . map ( |x| x. map ( |s| s. to_strbuf ( ) ) ) ,
543
+ NamesIterDynamic ( ref mut i) => i. next ( ) . map ( |x| x. as_ref ( ) . map ( |s| s. to_strbuf ( ) ) ) ,
544
+ }
545
+ }
498
546
}
499
547
500
548
/// NoExpand indicates literal string replacement.
@@ -612,22 +660,23 @@ pub struct Captures<'t> {
612
660
}
613
661
614
662
impl < ' t > Captures < ' t > {
663
+ #[ allow( experimental) ]
615
664
fn new ( re : & Regex , search : & ' t str , locs : CaptureLocs )
616
665
-> Option < Captures < ' t > > {
617
666
if !has_match ( & locs) {
618
667
return None
619
668
}
620
669
621
670
let named =
622
- if re. names . len ( ) == 0 {
671
+ if re. names_len ( ) == 0 {
623
672
None
624
673
} else {
625
674
let mut named = HashMap :: new ( ) ;
626
- for ( i, name) in re. names . iter ( ) . enumerate ( ) {
675
+ for ( i, name) in re. names_iter ( ) . enumerate ( ) {
627
676
match name {
628
- & None => { } ,
629
- & Some ( ref name) => {
630
- named. insert ( name. to_strbuf ( ) , i) ;
677
+ None => { } ,
678
+ Some ( name) => {
679
+ named. insert ( name, i) ;
631
680
}
632
681
}
633
682
}
@@ -862,9 +911,9 @@ fn exec(re: &Regex, which: MatchKind, input: &str) -> CaptureLocs {
862
911
863
912
fn exec_slice ( re : & Regex , which : MatchKind ,
864
913
input : & str , s : uint , e : uint ) -> CaptureLocs {
865
- match re . p {
866
- Dynamic ( ref prog) => vm:: run ( which, prog, input, s, e) ,
867
- Native ( exec ) => exec ( which, input, s, e) ,
914
+ match * re {
915
+ Dynamic ( Dynamic { ref prog, .. } ) => vm:: run ( which, prog, input, s, e) ,
916
+ Native ( Native { prog , .. } ) => prog ( which, input, s, e) ,
868
917
}
869
918
}
870
919
0 commit comments