diff --git a/proxmox-api-macro/src/api.rs b/proxmox-api-macro/src/api.rs index 91f74f84..96a76a12 100644 --- a/proxmox-api-macro/src/api.rs +++ b/proxmox-api-macro/src/api.rs @@ -90,7 +90,7 @@ impl TryFrom for Schema { properties: obj.into_iter().try_fold( Vec::new(), |mut properties, (key, value)| -> Result<_, syn::Error> { - properties.push((Ident::from(key), value.try_into()?)); + properties.push((key.into_ident()?, value.try_into()?)); Ok(properties) }, )?, diff --git a/proxmox-api-macro/src/util.rs b/proxmox-api-macro/src/util.rs index e55572bf..5a927d2c 100644 --- a/proxmox-api-macro/src/util.rs +++ b/proxmox-api-macro/src/util.rs @@ -10,6 +10,13 @@ use syn::spanned::Spanned; use syn::Token; /// A more relaxed version of Ident which allows hyphens. +/// +/// Note that this acts both as an Ident and as a String so that we can easily access an &str +/// (which Ident does not provide, instead, Ident always requires you to produce a newly owned +/// `String`). +/// Because of this the user also needs to be aware of the differences between idents and strings, +/// and therefore we do not implement `Into` anymore, but the user needs to explicitly ask +/// for it via the `.into_ident()` method. #[derive(Clone, Debug)] pub struct SimpleIdent(Ident, String); @@ -23,6 +30,19 @@ impl SimpleIdent { &self.1 } + #[inline] + pub unsafe fn into_ident_unchecked(self) -> Ident { + self.0 + } + + #[inline] + pub fn into_ident(self) -> Result { + if self.1.as_bytes().contains(&b'-') { + bail!(self.0 => "invalid identifier: '{}'", self.1); + } + Ok(unsafe { self.into_ident_unchecked() }) + } + //#[inline] //pub fn span(&self) -> Span { // self.0.span() @@ -50,12 +70,6 @@ impl From for SimpleIdent { } } -impl From for Ident { - fn from(this: SimpleIdent) -> Ident { - this.0 - } -} - impl fmt::Display for SimpleIdent { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f)