lib.rs (2705B)
1 /* -*- Mode: rust; rust-indent-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 extern crate uritemplate; 7 use uritemplate::UriTemplate; 8 9 use std::{ptr, str}; 10 11 use nserror::{nsresult, NS_ERROR_INVALID_ARG, NS_OK}; 12 extern crate nsstring; 13 use nsstring::nsACString; 14 15 use xpcom::{AtomicRefcnt, RefCounted, RefPtr}; 16 17 pub struct UriTemplateWrapper { 18 builder: UriTemplate, 19 refcnt: AtomicRefcnt, 20 } 21 22 impl UriTemplateWrapper { 23 fn new(input: &nsACString) -> Result<RefPtr<UriTemplateWrapper>, nsresult> { 24 let template = str::from_utf8(input).map_err(|_| NS_ERROR_INVALID_ARG)?; 25 let builder: *mut UriTemplateWrapper = Box::into_raw(Box::new(Self { 26 builder: UriTemplate::new(template), 27 refcnt: unsafe { AtomicRefcnt::new() }, 28 })); 29 unsafe { Ok(RefPtr::from_raw(builder).unwrap()) } 30 } 31 } 32 33 #[no_mangle] 34 pub unsafe extern "C" fn uri_template_addref(builder: &UriTemplateWrapper) { 35 builder.refcnt.inc(); 36 } 37 38 #[no_mangle] 39 pub unsafe extern "C" fn uri_template_release(builder: &UriTemplateWrapper) { 40 let rc = builder.refcnt.dec(); 41 if rc == 0 { 42 drop(Box::from_raw(ptr::from_ref(builder).cast_mut())); 43 } 44 } 45 46 // xpcom::RefPtr support 47 unsafe impl RefCounted for UriTemplateWrapper { 48 unsafe fn addref(&self) { 49 uri_template_addref(self); 50 } 51 unsafe fn release(&self) { 52 uri_template_release(self); 53 } 54 } 55 56 #[no_mangle] 57 pub extern "C" fn uri_template_new(input: &nsACString, result: &mut *const UriTemplateWrapper) { 58 *result = ptr::null_mut(); 59 if let Ok(builder) = UriTemplateWrapper::new(input) { 60 builder.forget(result); 61 } 62 } 63 64 #[no_mangle] 65 pub extern "C" fn uri_template_set( 66 builder: &mut UriTemplateWrapper, 67 name: &nsACString, 68 value: &nsACString, 69 ) -> nsresult { 70 let Ok(name_conv) = str::from_utf8(name) else { 71 return NS_ERROR_INVALID_ARG; 72 }; 73 let Ok(value_conv) = str::from_utf8(value) else { 74 return NS_ERROR_INVALID_ARG; 75 }; 76 builder.builder.set(name_conv, value_conv); 77 NS_OK 78 } 79 80 #[no_mangle] 81 pub extern "C" fn uri_template_set_int( 82 builder: &mut UriTemplateWrapper, 83 name: &nsACString, 84 value: i32, 85 ) -> nsresult { 86 let Ok(name_conv) = str::from_utf8(name) else { 87 return NS_ERROR_INVALID_ARG; 88 }; 89 builder.builder.set(name_conv, value.to_string()); 90 NS_OK 91 } 92 93 #[no_mangle] 94 pub extern "C" fn uri_template_build(builder: &mut UriTemplateWrapper, result: &mut nsACString) { 95 let res = builder.builder.build(); 96 result.assign(&res); 97 }