in uniffi_udl/src/converters/mod.rs [45:89]
fn convert(&self, ci: &mut InterfaceCollector) -> Result<VariantMetadata> {
if self.special.is_some() {
bail!("special operations not supported");
}
if let Some(weedle::interface::StringifierOrStatic::Stringifier(_)) = self.modifier {
bail!("stringifiers are not supported");
}
// OK, so this is a little weird.
// The syntax we use for enum interface members is `Name(type arg, ...);`, which parses
// as an anonymous operation where `Name` is the return type. We re-interpret it to
// use `Name` as the name of the variant.
if self.identifier.is_some() {
bail!("enum interface members must not have a method name");
}
let name: String = {
use weedle::types::{
NonAnyType::{self, Identifier},
ReturnType,
SingleType::NonAny,
Type::Single,
};
match &self.return_type {
ReturnType::Type(Single(NonAny(Identifier(id)))) => id.type_.0.to_owned(),
// Using recognized/parsed types as enum variant names can lead to the bail error because they match
// before `Identifier`. `Error` is one that's likely to be common, so we're circumventing what is
// likely a parsing issue here. As an example of the issue `Promise` (`Promise(PromiseType<'a>)`) as
// a variant matches the `Identifier` arm, but `DataView` (`DataView(MayBeNull<term!(DataView)>)`)
// fails.
ReturnType::Type(Single(NonAny(NonAnyType::Error(_)))) => "Error".to_string(),
_ => bail!("enum interface members must have plain identifiers as names"),
}
};
Ok(VariantMetadata {
name,
discr: None,
fields: self
.args
.body
.list
.iter()
.map(|arg| arg.convert(ci))
.collect::<Result<Vec<_>>>()?,
docstring: self.docstring.as_ref().map(|v| convert_docstring(&v.0)),
})
}