1 /*
2  * Copyright 2025 Matheus C. França
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 module ada.c.wrapper;
17 
18 private import ada.c.ada;
19 
20 @safe:
21 
22 struct AdaUrl
23 {
24     this(ParseOptions options) @nogc nothrow
25     {
26 
27         _url = options.url;
28     }
29 
30     ~this() @nogc nothrow
31     {
32         ada_free(_url);
33     }
34 
35     bool isValid() @nogc nothrow
36     {
37         return ada_is_valid(_url);
38     }
39 
40     string getOrigin() @nogc nothrow
41     {
42         auto owned = ada_get_origin(_url);
43         scope (exit)
44             ada_free_owned_string(owned);
45         return str_convert(owned);
46     }
47 
48     string getHref() @nogc nothrow
49     {
50         auto str = ada_get_href(_url);
51         return str_convert(str);
52     }
53 
54     string getUsername() @nogc nothrow
55     {
56         auto str = ada_get_username(_url);
57         return str_convert(str);
58     }
59 
60     string getPassword() @nogc nothrow
61     {
62         auto str = ada_get_password(_url);
63         return str_convert(str);
64     }
65 
66     string getPort() @nogc nothrow
67     {
68         auto str = ada_get_port(_url);
69         return str_convert(str);
70     }
71 
72     string getHash() @nogc nothrow
73     {
74         auto str = ada_get_hash(_url);
75         return str_convert(str);
76     }
77 
78     string getHost() @nogc nothrow
79     {
80         auto str = ada_get_host(_url);
81         return str_convert(str);
82     }
83 
84     string getHostname() @nogc nothrow
85     {
86         auto str = ada_get_hostname(_url);
87         return str_convert(str);
88     }
89 
90     string getPathname() @nogc nothrow
91     {
92         auto str = ada_get_pathname(_url);
93         return str_convert(str);
94     }
95 
96     SearchParams getSearch() @nogc nothrow
97     {
98         return SearchParams(ada_get_search(_url));
99     }
100 
101     string getSearchParams(SearchParams search) @nogc nothrow
102     {
103         auto str = search.toString();
104         return str_convert(str);
105     }
106 
107     string getProtocol() @nogc nothrow
108     {
109         auto str = ada_get_protocol(_url);
110         return str_convert(str);
111     }
112 
113     ubyte getHostType() @nogc nothrow
114     {
115         return ada_get_host_type(_url);
116     }
117 
118     ubyte getSchemeType() @nogc nothrow
119     {
120         return ada_get_scheme_type(_url);
121     }
122 
123     bool setHref(string input) @nogc nothrow
124     {
125         return ada_set_href(_url, &input[0], input.length);
126     }
127 
128     bool setHost(string input) @nogc nothrow
129     {
130         return ada_set_host(_url, &input[0], input.length);
131     }
132 
133     bool setHostname(string input) @nogc nothrow
134     {
135         return ada_set_hostname(_url, &input[0], input.length);
136     }
137 
138     bool setProtocol(string input) @nogc nothrow
139     {
140         return ada_set_protocol(_url, &input[0], input.length);
141     }
142 
143     bool setUsername(string input) @nogc nothrow
144     {
145         return ada_set_username(_url, &input[0], input.length);
146     }
147 
148     bool setPassword(string input) @nogc nothrow
149     {
150         return ada_set_password(_url, &input[0], input.length);
151     }
152 
153     bool setPort(string input) @nogc nothrow
154     {
155         return ada_set_port(_url, &input[0], input.length);
156     }
157 
158     bool setPathname(string input) @nogc nothrow
159     {
160         return ada_set_pathname(_url, &input[0], input.length);
161     }
162 
163     void setSearch(string input) @nogc nothrow
164     {
165         ada_set_search(_url, &input[0], input.length);
166     }
167 
168     void setHash(string input) @nogc nothrow
169     {
170         ada_set_hash(_url, &input[0], input.length);
171     }
172 
173     void clearPort() @nogc nothrow
174     {
175         ada_clear_port(_url);
176     }
177 
178     void clearHash() @nogc nothrow
179     {
180         ada_clear_hash(_url);
181     }
182 
183     void clearSearch() @nogc nothrow
184     {
185         ada_clear_search(_url);
186     }
187 
188     ada_url copy() @nogc nothrow
189     {
190         return ada_copy(_url);
191     }
192 
193     bool hasCredentials() @nogc nothrow
194     {
195         return ada_has_credentials(_url);
196     }
197 
198     bool hasEmptyHostname() @nogc nothrow
199     {
200         return ada_has_empty_hostname(_url);
201     }
202 
203     bool hasHostname() @nogc nothrow
204     {
205         return ada_has_hostname(_url);
206     }
207 
208     bool hasNonEmptyUsername() @nogc nothrow
209     {
210         return ada_has_non_empty_username(_url);
211     }
212 
213     bool hasNonEmptyPassword() @nogc nothrow
214     {
215         return ada_has_non_empty_password(_url);
216     }
217 
218     bool hasPort() @nogc nothrow
219     {
220         return ada_has_port(_url);
221     }
222 
223     bool hasPassword() @nogc nothrow
224     {
225         return ada_has_password(_url);
226     }
227 
228     bool hasHash() @nogc nothrow
229     {
230         return ada_has_hash(_url);
231     }
232 
233     bool hasSearch() @nogc nothrow
234     {
235         return ada_has_search(_url);
236     }
237 
238     const(ada_url_components)* getComponents() @nogc nothrow
239     {
240         return ada_get_components(_url);
241     }
242 
243     private ada_url _url;
244 }
245 
246 struct ParseOptions
247 {
248     this(string input) @nogc nothrow
249     {
250         _url = ada_parse(&input[0], input.length);
251     }
252 
253     this(string input, string base) @nogc nothrow
254     {
255         _url = ada_parse_with_base(&input[0], input.length, &base[0], base.length);
256     }
257 
258     @property ada_url url() @nogc nothrow
259     {
260         return _url;
261     }
262 
263     private ada_url _url;
264 }
265 
266 struct SearchParams
267 {
268     this(ref ada_string input) @nogc nothrow
269     {
270         _str = input;
271         _params = ada_parse_search_params(_str.data, _str.length);
272     }
273 
274     ~this() @nogc nothrow
275     {
276         ada_free_search_params_keys_iter(keys);
277         ada_free_search_params_values_iter(values);
278         ada_free_search_params_entries_iter(entries);
279         ada_free_search_params(_params);
280     }
281 
282     void append(ref string key, ref string value) @nogc nothrow
283     {
284         ada_search_params_append(_params, &key[0], key.length, &value[0], value.length);
285     }
286 
287     ada_owned_string toString() @nogc nothrow
288     {
289         return ada_search_params_to_string(_params);
290     }
291 
292     ada_string get(ref string key) @nogc nothrow
293     {
294         return ada_search_params_get(_params, &key[0], key.length);
295     }
296 
297     @property ada_url_search_params_keys_iter keys() @nogc nothrow
298     {
299         return ada_search_params_get_keys(_params);
300     }
301 
302     @property ada_url_search_params_values_iter values() @nogc nothrow
303     {
304         return ada_search_params_get_values(_params);
305     }
306 
307     @property ada_url_search_params_entries_iter entries() @nogc nothrow
308     {
309         return ada_search_params_get_entries(_params);
310     }
311 
312     Strings getAll(ref string key) @nogc nothrow
313     {
314         return Strings(ada_search_params_get_all(_params, &key[0], key.length));
315     }
316 
317     bool has(ref string key) @nogc nothrow
318     {
319         return ada_search_params_has(_params, &key[0], key.length);
320     }
321 
322     bool hasValue(ref string key, ref string value) @nogc nothrow
323     {
324         return ada_search_params_has_value(_params, &key[0], key.length, &value[0], value.length);
325     }
326 
327     size_t length() @nogc nothrow
328     {
329         return ada_search_params_size(_params);
330     }
331 
332     void reset() @nogc nothrow
333     {
334         ada_search_params_reset(_params, _str.data, _str.length);
335     }
336 
337     void remove(ref string key) @nogc nothrow
338     {
339         ada_search_params_remove(_params, &key[0], key.length);
340     }
341 
342     void removeValue(ref string key, ref string value) @nogc nothrow
343     {
344         ada_search_params_remove_value(_params, &key[0], key.length, &value[0], value.length);
345     }
346 
347     void set(ref string key, ref string value) @nogc nothrow
348     {
349         ada_search_params_set(_params, &key[0], key.length, &value[0], value.length);
350     }
351 
352     void sort() @nogc nothrow
353     {
354         ada_search_params_sort(_params);
355     }
356 
357     private
358     {
359         ada_url_search_params _params;
360         ada_string _str;
361     }
362 }
363 
364 struct Strings
365 {
366     this(ref ada_strings input) @nogc nothrow
367     {
368         _str = input;
369     }
370 
371     ~this() @nogc nothrow
372     {
373         ada_free_strings(_str);
374     }
375 
376     string getStr(size_t index) @nogc nothrow
377     {
378         return str_convert(ada_strings_get(_str, index));
379     }
380 
381     ada_string getData(size_t index) @nogc nothrow
382     {
383         return ada_strings_get(_str, index);
384     }
385 
386     size_t length() @nogc nothrow
387     {
388         return ada_strings_size(_str);
389     }
390 
391     private ada_strings _str;
392 }
393 
394 string str_convert(T)(ref T str) @trusted @nogc nothrow
395 {
396 
397     // pointer slicing not allowed in safe [checked] functions
398     static if (is(T == ada_string) || is(T == ada_owned_string))
399         return cast(string)(str.data[0 .. str.length]);
400     else
401         return cast(string)(str);
402 }