char/avril
(wip) why'd you have to go and make things so complicaaaaated?
git clone https://git.t4t.associates/char/avril
bf382b3
main
1use std:: convert:: Infallible ; 2use std:: io; 3 4use :: url::{ Position , Url , form_urlencoded, quirks}; 5use avril_core::{ Extension , Op }; 6 7fn parts ( url : Url ) ->Vec < String > { 8// Blob origins inherit only HTTP(S), not every scheme accepted by rust-url's origin API. 9let origin =if url. scheme () =="blob" { 10Url :: parse ( url. path ()) 11. ok () 12. filter ( |inner|matches! ( inner. scheme (), "http" |"https" )) 13. map_or_else ( ||"null" . into (), |inner| quirks:: origin ( & inner)) 14} else { 15 quirks:: origin ( & url) 16}; 17// Order is shared with the component table in url.js. 18vec! [ 19 quirks:: href ( & url). into (), 20 origin, 21 quirks:: protocol ( & url). into (), 22 quirks:: username ( & url). into (), 23 quirks:: password ( & url). into (), 24 quirks:: host ( & url). into (), 25 quirks:: hostname ( & url). into (), 26 quirks:: port ( & url). into (), 27 quirks:: pathname ( & url). into (), 28 quirks:: search ( & url). into (), 29 quirks:: hash ( & url). into (), 30] 31} 32 33pub fn init () ->Extension { 34Extension { 35name : "ext:url" , 36dependencies : & [ "ext:web" ], 37ops : vec! [ 38Op :: new ( "op_url_parse" , |( input, base): ( String , Option < String >) |{ 39let parsed =( ||{ 40let base = base. as_deref (). map ( Url :: parse). transpose (). ok () ?; 41Url :: options () 42. base_url ( base. as_ref ()) 43. parse ( & input) 44. ok () 45. map ( parts) 46})(); 47Ok ::< _ , Infallible >( parsed) 48}), 49Op :: new ( 50"op_url_set" , 51 |( href, component, value): ( String , String , String ) |{ 52let mut url =Url :: parse ( & href). map_err ( io:: Error :: other) ?; 53let original = url. clone (); 54match component. as_str () { 55"href" =>{ 56if quirks:: set_href ( & mut url, & value). is_err () { 57return Ok ( None ); 58} 59} 60"protocol" =>{ 61let _ = quirks:: set_protocol ( & mut url, & value); 62} 63"username" =>{ 64let _ = quirks:: set_username ( & mut url, & value); 65} 66"password" =>{ 67let _ = quirks:: set_password ( & mut url, & value); 68} 69"host" =>{ 70let _ = quirks:: set_host ( & mut url, & value); 71} 72"hostname" =>{ 73let _ = quirks:: set_hostname ( & mut url, & value); 74} 75"port" =>{ 76let _ = quirks:: set_port ( & mut url, & value); 77} 78"pathname" => quirks:: set_pathname ( & mut url, & value), 79"search" => quirks:: set_search ( & mut url, & value), 80"hash" => quirks:: set_hash ( & mut url, & value), 81 _ =>{ 82return Err ( io:: Error :: new ( 83 io:: ErrorKind :: InvalidInput , 84"Unknown URL component" , 85)); 86} 87} 88// rust-url setters can omit the /. prefix that disambiguates a hostless // path. 89let href =if url. host_str (). is_none () 90 && !url. cannot_be_a_base () 91 && url. path (). starts_with ( "//" ) 92{ 93format! ( "{}:/.{}" , url. scheme (), & url[ Position :: BeforePath ..]) 94} else { 95 url. to_string () 96}; 97let updated =parts ( url); 98let reparsed =Url :: parse ( & href). ok (). map ( parts); 99// Never retain components that change meaning when the next op reparses href. 100Ok ( Some ( match reparsed{ 101Some ( parsed) if parsed[ 1 ..] == updated[ 1 ..] => parsed, 102 _ =>parts ( original), 103})) 104}, 105), 106Op :: new ( "op_url_search_parse" , |query : String |{ 107Ok ::< _ , Infallible >( 108 form_urlencoded:: parse ( query. as_bytes ()) 109. into_owned () 110. collect ::< Vec < _ >>(), 111) 112}), 113Op :: new ( "op_url_search_serialize" , |pairs : Vec <( String , String )> |{ 114Ok ::< _ , Infallible >( 115 form_urlencoded:: Serializer :: new ( String :: new ()) 116. extend_pairs ( pairs) 117. finish (), 118) 119}), 120], 121modules : & [ 122( 123"ext:url/main.js" , 124include_str! ( concat! ( env! ( "OUT_DIR" ), "/main.js" )), 125), 126( 127"ext:url/url.js" , 128include_str! ( concat! ( env! ( "OUT_DIR" ), "/url.js" )), 129), 130( 131"ext:url/search_params.js" , 132include_str! ( concat! ( env! ( "OUT_DIR" ), "/search_params.js" )), 133), 134( 135"ext:url/state.js" , 136include_str! ( concat! ( env! ( "OUT_DIR" ), "/state.js" )), 137), 138], 139entry_point : Some ( "ext:url/main.js" ), 140} 141}