1 module awebview.wrapper.weburl;
2 
3 import awebview.wrapper.cpp;
4 import awebview.wrapper.webstring : WebStringCpp, WebString;
5 import awebview.wrapper.weakref;
6 
7 import carbon.nonametype;
8 import carbon.memory;
9 
10 
11 struct WebURL
12 {
13     alias PayloadType(This) = typeof(This.init.payload);
14 
15 
16     @property
17     ref WebURLCpp payload() nothrow @nogc
18     {
19         if(!_instance.refCountedStore.isInitialized)
20             __ctor(cast(awebview.wrapper.cpp.WebURL)null);
21 
22         return _instance.refCountedPayload;
23     }
24 
25 
26     @property
27     ref inout(WebURLCpp) payload(this T)() inout nothrow @nogc
28     {
29         if(this._instance.refCountedStore.isInitialized)
30             return *cast(typeof(return)*)&(this._instance.refCountedPayload());
31         else
32             return *cast(typeof(return)*)WebURLCpp._emptyInstance;
33     }
34 
35 
36     this(Char)(in Char[] url) @nogc nothrow
37     if(is(typeof(WebStringCpp(url)) == WebStringCpp))
38     {
39         _instance = Instance(RefCountedNoGC!WebURLCpp(url));
40     }
41 
42 
43     this(in WebString str) @nogc nothrow
44     {
45         _instance.obj = str.payload;
46     }
47 
48 
49     this(const ref WebStringCpp str) @nogc nothrow
50     {
51         _instance = Instance(RefCountedNoGC!WebURLCpp(str));
52     }
53 
54 
55     this(const awebview.wrapper.cpp.WebString cppws) @nogc nothrow
56     {
57         _instance = Instance(RefCountedNoGC!WebURLCpp(cppws));
58     }
59 
60 
61     this(const awebview.wrapper.cpp.WebURL cppwurl) @nogc nothrow
62     {
63         _instance = Instance(RefCountedNoGC!WebURLCpp(cppwurl));
64     }
65 
66 
67     @property
68     awebview.wrapper.cpp.WebURL cppObj() nothrow @nogc
69     {
70         return payload.cppObj;
71     }
72 
73 
74     @property
75     inout(const(awebview.wrapper.cpp.WebURL)) cppObj(this T)() inout nothrow @nogc
76     {
77         return this.payload.cppObj;
78     }
79 
80 
81     @property
82     WeakRef!(PayloadType!This) weakRef(this This)() inout nothrow @trusted @nogc
83     {
84         alias WCpp = PayloadType!This;
85         return refP!WCpp(cast(WCpp*)&(cast(This*)&this).payload());
86     }
87 
88 
89     void opAssign(WebURL url)
90     {
91         _instance.obj = url.payload;
92     }
93 
94 
95     void opAssign(ref const WebURLCpp url)
96     {
97         this = WebURL(url.cppObj);
98     }
99 
100 
101     void opAssign(Char)(in Char[] str)
102     if(is(typeof(WebString(str)) == WebString))
103     {
104         WebURLCpp url = WebString(str);
105         this = url;
106     }
107 
108 
109     bool isValid() const @property nothrow @nogc
110     {
111         return payload.isValid;
112     }
113 
114 
115     bool empty() const @property nothrow @nogc
116     {
117         return payload.empty;
118     }
119 
120 
121     WebString spec() const @property nothrow @nogc
122     {
123         return payload.spec;
124     }
125 
126 
127     WebString scheme() const @property nothrow @nogc
128     {
129         return payload.scheme;
130     }
131 
132 
133     WebString username() const @property nothrow @nogc
134     {
135         return payload.username;
136     }
137 
138 
139     WebString password() const @property nothrow @nogc
140     {
141         return payload.password;
142     }
143 
144 
145     WebString host() const @property nothrow @nogc
146     {
147         return payload.host;
148     }
149 
150 
151     WebString port() const @property nothrow @nogc
152     {
153         return payload.port;
154     }
155 
156 
157     WebString path() const @property nothrow @nogc
158     {
159         return payload.path;
160     }
161 
162 
163     WebString query() const @property nothrow @nogc
164     {
165         return payload.query;
166     }
167 
168 
169     WebString anchor() const @property nothrow @nogc
170     {
171         return payload.anchor;
172     }
173 
174 
175     WebString filename() const @property nothrow @nogc
176     {
177         return payload.filename;
178     }
179 
180 
181     bool opEquals()(auto ref const WebURL rhs) const
182     {
183         return this.payload == rhs.payload;
184     }
185 
186 
187     bool opEquals(ref const WebURLCpp rhs) const
188     {
189         return this.payload == rhs;
190     }
191 
192 
193     bool opEquals(Char)(in Char[] rhs) const
194     if(is(typeof(WebString(rhs)) == WebString))
195     {
196         WebURLCpp rhsURL = rhs;
197         return this == rhsURL;
198     }
199 
200 
201     int opCmp()(auto ref const WebURL rhs) const
202     {
203         return this.payload.opCmp(rhs.payload);
204     }
205 
206 
207     int opCmp(ref const WebURLCpp rhs) const
208     {
209         return this.payload.opCmp(rhs);
210     }
211 
212 
213     int opCmp(Char)(in Char[] rhs) const
214     {
215         WebURLCpp url = rhs;
216         return this.payload.opCmp(url);
217     }
218 
219 
220   private:
221     /// RefCountedNoGC!WebURLCpp _instance;
222     Instance _instance;
223 
224     alias Instance = typeof(_dummyTypeCreate());
225 
226     static auto _dummyTypeCreate()
227     {
228         static struct R
229         {
230             RefCountedNoGC!WebURLCpp obj;
231             alias obj this;
232         }
233 
234         return R();
235     }
236 }
237 
238 struct WebURLCpp
239 {
240   nothrow @nogc
241   {
242     this(Char)(in Char[] url)
243     if(is(typeof(WebStringCpp(url)) == WebStringCpp))
244     {
245         WebStringCpp str = url;
246         this(str);
247     }
248 
249 
250     this(in WebString str)
251     {
252         this(str.cppObj);
253     }
254 
255 
256     this(const ref WebStringCpp str)
257     {
258         this(str.cppObj);
259     }
260 
261 
262     this(const awebview.wrapper.cpp.WebString cppws)
263     {
264         WebURLMember.ctor(this.cppObj!false, cppws);
265     }
266 
267 
268     this(const awebview.wrapper.cpp.WebURL cppwurl)
269     {
270         if(cppwurl is null)
271             WebURLMember.ctor(this.cppObj!false);
272         else
273             WebURLMember.ctor(this.cppObj!false, cppwurl);
274     }
275 
276 
277     this(this)
278     {
279         if(this.cppField.instance_ !is null){
280             typeof(_field) f;
281             WebURLCpp* vp = cast(WebURLCpp*)cast(void*)&f;
282             WebURLMember.ctor(vp.cppObj!false, this.cppObj);
283             this._field = vp._field;
284         }
285     }
286 
287 
288     ~this()
289     {
290         if(cppField.instance_ !is null)
291             WebURLMember.dtor(this.cppObj!false);
292     }
293 
294 
295     private
296     ref inout(awebview.wrapper.cpp.WebURL.Field)
297         cppField() inout pure nothrow @trusted @property @nogc
298     { return *cast(typeof(return)*)_field.ptr; }
299 
300 
301     CppWebURL cppObj(bool withInitialize = true)() nothrow @trusted @property @nogc
302     {
303         CppWebURL ret = cast(CppWebURL)cast(void*)_field.ptr;
304 
305       static if(withInitialize)
306         if(cppField.instance_ is null)
307             WebURLMember.ctor(ret);
308 
309         return ret;
310     }
311 
312 
313     inout(CppWebURL) cppObj() inout nothrow @trusted @property @nogc
314     {
315         if(cppField.instance_ is null)
316             return cast(inout(CppWebURL))cast(inout(void)*)&_emptyInstance._field;
317         else
318             return cast(inout(CppWebURL))cast(inout(void)*)&_field;
319     }
320 
321 
322     auto weakRef(this T)() pure nothrow @trusted @property @nogc
323     {
324         return refP!T(cast(T*)&this);
325     }
326 
327 
328     void opAssign()(auto ref const WebURLCpp url)
329     {
330         WebURLMember.opAssign(this.cppObj, url.cppObj);
331     }
332 
333 
334     void opAssign(Char)(in Char[] str)
335     if(is(typeof(WebString(str)) == WebString))
336     {
337         WebURLCpp url = WebString(str);
338         this = url;
339     }
340 
341 
342     bool isValid() const @property
343     {
344         return WebURLMember.IsValid(this.cppObj);
345     }
346 
347 
348     bool empty() const @property
349     {
350         return WebURLMember.IsEmpty(this.cppObj);
351     }
352 
353 
354     WebString getStringProperty(alias f)() const @property
355     {
356         WebString str;
357         f(this.cppObj, str.cppObj);
358         return str;
359     }
360 
361 
362     alias spec = getStringProperty!(WebURLMember.spec);
363     alias scheme = getStringProperty!(WebURLMember.scheme);
364     alias username = getStringProperty!(WebURLMember.username);
365     alias password = getStringProperty!(WebURLMember.password);
366     alias host = getStringProperty!(WebURLMember.host);
367     alias port = getStringProperty!(WebURLMember.port);
368     alias path = getStringProperty!(WebURLMember.path);
369     alias query = getStringProperty!(WebURLMember.query);
370     alias anchor = getStringProperty!(WebURLMember.anchor);
371     alias filename = getStringProperty!(WebURLMember.filename);
372 
373   }
374 
375     bool opEquals()(auto ref const WebURLCpp rhs) const
376     {
377         return WebURLMember.opEquals(this.cppObj, rhs.cppObj);
378     }
379 
380 
381     bool opEquals(Char)(in Char[] rhs) const
382     if(is(typeof(WebString(rhs)) == WebString))
383     {
384         WebURLCpp rhsURL = rhs;
385         return this == rhsURL;
386     }
387 
388 
389     int opCmp()(auto ref const WebURLCpp rhs) const
390     {
391         return WebURLMember.opCmp(this.cppObj, rhs.cppObj);
392     }
393 
394 
395     static
396     auto weakRef(H)(H handle) @trusted
397     if(is(H : const(awebview.wrapper.cpp.WebURL)))
398     {
399       static if(is(H == awebview.wrapper.cpp.WebURL))
400         WebURLCpp* p = cast(WebURLCpp*)cast(void*)handle;
401       else static if(is(H == const(awebview.wrapper.cpp.WebURL)))
402         const(WebURLCpp)* p = cast(const(WebURLCpp*))cast(void*)handle;
403       else
404         immutable(WebURLCpp)* p = cast(immutable(WebURLCpp)*)cast(void*)handle;
405 
406         return refP(p);
407     }
408 
409 
410   private:
411     alias CppWebURL = awebview.wrapper.cpp.WebURL;
412     ubyte[CppWebURL.Field.sizeof] _field;
413 
414     static shared immutable(WebURLCpp*) _emptyInstance;
415 
416     shared static this()
417     {
418         WebURLCpp* p = new WebURLCpp;
419         WebURLMember.ctor(p.cppObj!false);
420         _emptyInstance = cast(immutable)p;
421     }
422 }
423 
424 
425 unittest
426 {
427     WebURL empty_;
428     assert(empty_ == empty_);
429     assert(!empty_.isValid);
430     assert(empty_.empty);
431     assert(empty_ == "");
432 }
433 
434 
435 unittest
436 {
437     WebURL url = "http://www.google.com";
438     assert(url.isValid);
439 
440     url = "foo";
441     assert(!url.isValid);
442     url = "file://foo/foo.txt";
443     assert(url.isValid);
444     assert(url.filename == "foo.txt");
445 
446     WebURL url2 = url;
447     assert(url2.cppObj is url.cppObj);  // reference copy
448     assert(url2 == url);
449 }
450 
451 
452 unittest
453 {
454     WebURLCpp url;
455 
456     auto wr1 = url.weakRef;
457     auto wr2 = url.cppObj.weakRef!WebURLCpp;
458     assert(url.cppObj is wr1.cppObj);
459     assert(url.cppObj is wr2.cppObj);
460 
461     url = "file://foo/foo.txt";
462     assert(url.cppObj is wr1.cppObj);
463     assert(url.cppObj is wr2.cppObj);
464 }