1
- use crate :: identifier:: MAX_IDENTIFIER_LEN ;
1
+ use std:: {
2
+ ops:: Deref ,
3
+ str:: FromStr ,
4
+ } ;
5
+
6
+ use crate :: {
7
+ identifier:: MAX_IDENTIFIER_LEN ,
8
+ FunctionName ,
9
+ } ;
2
10
3
11
pub fn check_valid_path_component ( s : & str ) -> anyhow:: Result < ( ) > {
4
12
if s. len ( ) > MAX_IDENTIFIER_LEN {
@@ -21,3 +29,50 @@ pub fn check_valid_path_component(s: &str) -> anyhow::Result<()> {
21
29
}
22
30
Ok ( ( ) )
23
31
}
32
+
33
+ #[ derive( Debug , Clone , Eq , PartialEq , Hash , Ord , PartialOrd ) ]
34
+ pub struct PathComponent ( String ) ;
35
+
36
+ impl FromStr for PathComponent {
37
+ type Err = anyhow:: Error ;
38
+
39
+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
40
+ check_valid_path_component ( s) ?;
41
+ Ok ( Self ( s. to_owned ( ) ) )
42
+ }
43
+ }
44
+
45
+ impl Deref for PathComponent {
46
+ type Target = str ;
47
+
48
+ fn deref ( & self ) -> & Self :: Target {
49
+ & self . 0
50
+ }
51
+ }
52
+
53
+ impl From < PathComponent > for String {
54
+ fn from ( p : PathComponent ) -> Self {
55
+ p. 0
56
+ }
57
+ }
58
+
59
+ impl From < FunctionName > for PathComponent {
60
+ fn from ( function_name : FunctionName ) -> Self {
61
+ function_name
62
+ . parse ( )
63
+ . expect ( "FunctionName isn't a valid PathComponent" )
64
+ }
65
+ }
66
+
67
+ #[ cfg( any( test, feature = "testing" ) ) ]
68
+ impl proptest:: arbitrary:: Arbitrary for PathComponent {
69
+ type Parameters = ( ) ;
70
+ type Strategy = proptest:: strategy:: BoxedStrategy < Self > ;
71
+
72
+ fn arbitrary_with ( ( ) : Self :: Parameters ) -> Self :: Strategy {
73
+ use proptest:: prelude:: * ;
74
+ "_?[a-zA-Z0-9_]{1,60}(\\ .js)?"
75
+ . prop_filter_map ( "Invalid path component" , |s| s. parse ( ) . ok ( ) )
76
+ . boxed ( )
77
+ }
78
+ }
0 commit comments