/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::{
borrow::Cow,
convert::{TryFrom, TryInto},
};
use libc::c_double; use nserror::{nsresult, NS_ERROR_CANNOT_CONVERT_DATA, NS_OK}; use nsstring::{nsACString, nsAString, nsCString, nsString}; use xpcom::{getter_addrefs, interfaces::nsIVariant, RefPtr};
// These are the relevant parts of the nsXPTTypeTag enum in xptinfo.h, // which nsIVariant.idl reflects into the nsIDataType struct class and uses // to constrain the values of nsIVariant::dataType. #[repr(u16)] #[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)] pubenum DataType {
Int32 = 2,
Int64 = 3,
Double = 9,
Bool = 10,
Void = 13,
CharStr = 15,
WCharStr = 16,
StringSizeIs = 20,
WStringSizeIs = 21,
Utf8String = 24,
CString = 25,
AString = 26,
EmptyArray = 254,
Empty = 255,
}
impl TryFrom<u16> for DataType { type Error = nsresult;
/// Converts a raw type tag for an `nsIVariant` into a `DataType` variant. /// Returns `NS_ERROR_CANNOT_CONVERT_DATA` if the type isn't one that we /// support. fn try_from(raw: u16) -> Result<Self, Self::Error> {
Ok(match raw { 2 => DataType::Int32, 3 => DataType::Int64, 9 => DataType::Double, 10 => DataType::Bool, 13 => DataType::Void, 15 => DataType::CharStr, 16 => DataType::WCharStr, 20 => DataType::StringSizeIs, 21 => DataType::WStringSizeIs, 24 => DataType::Utf8String, 25 => DataType::CString, 26 => DataType::AString, 254 => DataType::EmptyArray, 255 => DataType::Empty,
_ => Err(NS_ERROR_CANNOT_CONVERT_DATA)?,
})
}
}
/// Extension methods implemented on `nsIVariant` types, to make them easier /// to work with. pubtrait NsIVariantExt { /// Returns the raw type tag for this variant. Call /// `DataType::try_from()` on this tag to turn it into a `DataType`. fn get_data_type(&self) -> u16;
/// Tries to clone this variant, failing with `NS_ERROR_CANNOT_CONVERT_DATA` /// if its type is unsupported. fn try_clone(&self) -> Result<RefPtr<nsIVariant>, nsresult>;
}
/// Implements traits to convert between variants and their types.
macro_rules! variant {
($typ:ident, $constructor:ident, $getter:ident) => { impl VariantType for $typ { fn type_name() -> Cow<'static, str> {
stringify!($typ).into()
} fn into_variant(self) -> RefPtr<nsIVariant> { // getter_addrefs returns a Result<RefPtr<T>, nsresult>, // but we know that our $constructor is infallible, so we can // safely unwrap and return the RefPtr.
getter_addrefs(|p| { unsafe { $constructor(self.into(), p) };
NS_OK
})
.unwrap()
} fn from_variant(variant: &nsIVariant) -> Result<$typ, nsresult> { letmut result = $typ::default(); let rv = unsafe { variant.$getter(&mut result) }; if rv.succeeded() {
Ok(result)
} else {
Err(rv)
}
}
}
};
(* $typ:ident, $constructor:ident, $getter:ident) => { impl VariantType for $typ { fn type_name() -> Cow<'static, str> {
stringify!($typ).into()
} fn into_variant(self) -> RefPtr<nsIVariant> { // getter_addrefs returns a Result<RefPtr<T>, nsresult>, // but we know that our $constructor is infallible, so we can // safely unwrap and return the RefPtr.
getter_addrefs(|p| { unsafe { $constructor(&*self, p) };
NS_OK
})
.unwrap()
} fn from_variant(variant: &nsIVariant) -> Result<$typ, nsresult> { letmut result = $typ::new(); let rv = unsafe { variant.$getter(&mut *result) }; if rv.succeeded() {
Ok(result)
} else {
Err(rv)
}
}
}
};
}
// The unit type (()) is a reasonable equivalation of the null variant. // The macro can't produce its implementations of VariantType, however, // so we implement them concretely. impl VariantType for () { fn type_name() -> Cow<'static, str> { "()".into()
} fn into_variant(self) -> RefPtr<nsIVariant> { // getter_addrefs returns a Result<RefPtr<T>, nsresult>, // but we know that NS_NewStorageNullVariant is infallible, so we can // safely unwrap and return the RefPtr.
getter_addrefs(|p| { unsafe { NS_NewStorageNullVariant(p) };
NS_OK
})
.unwrap()
} fn from_variant(_variant: &nsIVariant) -> Result<Self, nsresult> {
Ok(())
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.