@@ -50,144 +50,135 @@ pub fn parse(uri_string: String) -> Result(Uri, Nil) {
50
50
do_parse ( uri_string )
51
51
}
52
52
53
- fn do_parse ( uri_string : String ) -> Result ( Uri , Nil ) {
54
- // From https://tools.ietf.org/html/rfc3986#appendix-B
55
- let pattern =
56
- // 12 3 4 5 6 7 8
57
- "^(([a-z][a-z0-9\\ +\\ -\\ .]*):)?(//([^/?#]*))?([^?#]*)(\\ ?([^#]*))?(#.*)?"
58
- let matches =
59
- pattern
60
- |> regex_submatches ( uri_string )
61
- |> pad_list ( 8 )
62
-
63
- let # ( scheme , authority , path , query , fragment ) = case matches {
64
- [
65
- _scheme_with_colon ,
66
- scheme ,
67
- authority_with_slashes ,
68
- _authority ,
69
- path ,
70
- query_with_question_mark ,
71
- _query ,
72
- fragment ,
73
- ] -> # (
74
- scheme ,
75
- authority_with_slashes ,
76
- path ,
77
- query_with_question_mark ,
78
- fragment ,
79
- )
80
- _ -> # ( None , None , None , None , None )
81
- }
82
-
83
- let scheme = noneify_empty_string ( scheme )
84
- let path = option . unwrap ( path , "" )
85
- let query = noneify_query ( query )
86
- let # ( userinfo , host , port ) = split_authority ( authority )
87
- let fragment =
88
- fragment
89
- |> option . to_result ( Nil )
90
- |> result . then ( string . pop_grapheme )
91
- |> result . map ( pair . second )
92
- |> option . from_result
93
- let port = case port {
94
- None -> default_port ( scheme )
95
- _ -> port
96
- }
97
- let scheme =
98
- scheme
99
- |> noneify_empty_string
100
- |> option . map ( string . lowercase )
101
- Ok ( Uri (
102
- scheme : scheme ,
103
- userinfo : userinfo ,
104
- host : host ,
105
- port : port ,
106
- path : path ,
107
- query : query ,
108
- fragment : fragment ,
109
- ) )
53
+ if erlang {
54
+ external fn do_parse ( String ) -> Result ( Uri , Nil ) =
55
+ "gleam_stdlib" "uri_parse"
110
56
}
111
57
112
- fn default_port ( scheme : Option ( String ) ) -> Option ( Int ) {
113
- case scheme {
114
- Some ( "ftp" ) -> Some ( 21 )
115
- Some ( "sftp" ) -> Some ( 22 )
116
- Some ( "tftp" ) -> Some ( 69 )
117
- Some ( "http" ) -> Some ( 80 )
118
- Some ( "https" ) -> Some ( 443 )
119
- Some ( "ldap" ) -> Some ( 389 )
120
- _ -> None
58
+ if javascript {
59
+ fn do_parse ( uri_string : String ) -> Result ( Uri , Nil ) {
60
+ // From https://tools.ietf.org/html/rfc3986#appendix-B
61
+ let pattern =
62
+ // 12 3 4 5 6 7 8
63
+ "^(([a-z][a-z0-9\\ +\\ -\\ .]*):)?(//([^/?#]*))?([^?#]*)(\\ ?([^#]*))?(#.*)?"
64
+ let matches =
65
+ pattern
66
+ |> regex_submatches ( uri_string )
67
+ |> pad_list ( 8 )
68
+
69
+ let # ( scheme , authority , path , query , fragment ) = case matches {
70
+ [
71
+ _scheme_with_colon ,
72
+ scheme ,
73
+ authority_with_slashes ,
74
+ _authority ,
75
+ path ,
76
+ query_with_question_mark ,
77
+ _query ,
78
+ fragment ,
79
+ ] -> # (
80
+ scheme ,
81
+ authority_with_slashes ,
82
+ path ,
83
+ query_with_question_mark ,
84
+ fragment ,
85
+ )
86
+ _ -> # ( None , None , None , None , None )
87
+ }
88
+
89
+ let scheme = noneify_empty_string ( scheme )
90
+ let path = option . unwrap ( path , "" )
91
+ let query = noneify_query ( query )
92
+ let # ( userinfo , host , port ) = split_authority ( authority )
93
+ let fragment =
94
+ fragment
95
+ |> option . to_result ( Nil )
96
+ |> result . then ( string . pop_grapheme )
97
+ |> result . map ( pair . second )
98
+ |> option . from_result
99
+ let scheme =
100
+ scheme
101
+ |> noneify_empty_string
102
+ |> option . map ( string . lowercase )
103
+ Ok ( Uri (
104
+ scheme : scheme ,
105
+ userinfo : userinfo ,
106
+ host : host ,
107
+ port : port ,
108
+ path : path ,
109
+ query : query ,
110
+ fragment : fragment ,
111
+ ) )
121
112
}
122
- }
123
113
124
- fn regex_submatches ( pattern : String , string : String ) -> List ( Option ( String ) ) {
125
- pattern
126
- |> regex . compile ( regex . Options ( case_insensitive : True , multi_line : False ) )
127
- |> result . nil_error
128
- |> result . map ( regex . scan ( _, string ) )
129
- |> result . then ( list . head )
130
- |> result . map ( fn ( m : regex . Match ) { m . submatches } )
131
- |> result . unwrap ( [ ] )
132
- }
114
+ fn regex_submatches ( pattern : String , string : String ) -> List ( Option ( String ) ) {
115
+ pattern
116
+ |> regex . compile ( regex . Options ( case_insensitive : True , multi_line : False ) )
117
+ |> result . nil_error
118
+ |> result . map ( regex . scan ( _, string ) )
119
+ |> result . then ( list . head )
120
+ |> result . map ( fn ( m : regex . Match ) { m . submatches } )
121
+ |> result . unwrap ( [ ] )
122
+ }
133
123
134
- fn noneify_query ( x : Option ( String ) ) -> Option ( String ) {
135
- case x {
136
- None -> None
137
- Some ( x ) ->
138
- case string . pop_grapheme ( x ) {
139
- Ok ( # ( "?" , query ) ) -> Some ( query )
140
- _ -> None
141
- }
124
+ fn noneify_query ( x : Option ( String ) ) -> Option ( String ) {
125
+ case x {
126
+ None -> None
127
+ Some ( x ) ->
128
+ case string . pop_grapheme ( x ) {
129
+ Ok ( # ( "?" , query ) ) -> Some ( query )
130
+ _ -> None
131
+ }
132
+ }
142
133
}
143
- }
144
134
145
- fn noneify_empty_string ( x : Option ( String ) ) -> Option ( String ) {
146
- case x {
147
- Some ( "" ) | None -> None
148
- Some ( _ ) -> x
135
+ fn noneify_empty_string ( x : Option ( String ) ) -> Option ( String ) {
136
+ case x {
137
+ Some ( "" ) | None -> None
138
+ Some ( _ ) -> x
139
+ }
149
140
}
150
- }
151
141
152
- // Split an authority into its userinfo, host and port parts.
153
- fn split_authority (
154
- authority : Option ( String ) ,
155
- ) -> # ( Option ( String ) , Option ( String ) , Option ( Int ) ) {
156
- case option . unwrap ( authority , "" ) {
157
- "" -> # ( None , None , None )
158
- "//" -> # ( None , Some ( "" ) , None )
159
- authority -> {
160
- let matches =
161
- "^(//)?((.*)@)?(\\ [[a-zA-Z0-9:.]*\\ ]|[^:]*)(:(\\ d*))?"
162
- |> regex_submatches ( authority )
163
- |> pad_list ( 6 )
164
- case matches {
165
- [ _ , _ , userinfo , host , _ , port ] -> {
166
- let userinfo = noneify_empty_string ( userinfo )
167
- let host = noneify_empty_string ( host )
168
- let port =
169
- port
170
- |> option . unwrap ( "" )
171
- |> int . parse
172
- |> option . from_result
173
- # ( userinfo , host , port )
142
+ // Split an authority into its userinfo, host and port parts.
143
+ fn split_authority (
144
+ authority : Option ( String ) ,
145
+ ) -> # ( Option ( String ) , Option ( String ) , Option ( Int ) ) {
146
+ case option . unwrap ( authority , "" ) {
147
+ "" -> # ( None , None , None )
148
+ "//" -> # ( None , Some ( "" ) , None )
149
+ authority -> {
150
+ let matches =
151
+ "^(//)?((.*)@)?(\\ [[a-zA-Z0-9:.]*\\ ]|[^:]*)(:(\\ d*))?"
152
+ |> regex_submatches ( authority )
153
+ |> pad_list ( 6 )
154
+ case matches {
155
+ [ _ , _ , userinfo , host , _ , port ] -> {
156
+ let userinfo = noneify_empty_string ( userinfo )
157
+ let host = noneify_empty_string ( host )
158
+ let port =
159
+ port
160
+ |> option . unwrap ( "" )
161
+ |> int . parse
162
+ |> option . from_result
163
+ # ( userinfo , host , port )
164
+ }
165
+ _ -> # ( None , None , None )
174
166
}
175
- _ -> # ( None , None , None )
176
167
}
177
168
}
178
169
}
179
- }
180
170
181
- fn pad_list ( list : List ( Option ( a) ) , size : Int ) -> List ( Option ( a) ) {
182
- list
183
- |> list . append ( list . repeat ( None , extra_required ( list , size ) ) )
184
- }
171
+ fn pad_list ( list : List ( Option ( a) ) , size : Int ) -> List ( Option ( a) ) {
172
+ list
173
+ |> list . append ( list . repeat ( None , extra_required ( list , size ) ) )
174
+ }
185
175
186
- fn extra_required ( list : List ( a) , remaining : Int ) -> Int {
187
- case list {
188
- _ if remaining == 0 -> 0
189
- [ ] -> remaining
190
- [ _ , .. xs ] -> extra_required ( xs , remaining - 1 )
176
+ fn extra_required ( list : List ( a) , remaining : Int ) -> Int {
177
+ case list {
178
+ _ if remaining == 0 -> 0
179
+ [ ] -> remaining
180
+ [ _ , .. xs ] -> extra_required ( xs , remaining - 1 )
181
+ }
191
182
}
192
183
}
193
184
0 commit comments