fix(macros/generate/host): Add unified support for conversions
These include from the c type to rust, vice versa.
This commit is contained in:
parent
3d35d395f3
commit
b5f5ae8b03
|
@ -35,24 +35,7 @@ impl Enumeration {
|
|||
.collect();
|
||||
|
||||
let states: Vec<TokenStream2> = self.states.iter().map(DocIdentifier::to_rust).collect();
|
||||
let paired_type = {
|
||||
let path = &self
|
||||
.identifier
|
||||
.variant
|
||||
.to_rust_path()
|
||||
.expect("This should always be some for enums");
|
||||
|
||||
let ident = &self.identifier.to_rust();
|
||||
if path.is_empty() {
|
||||
quote! {
|
||||
crate :: #ident
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#path :: #ident
|
||||
}
|
||||
}
|
||||
};
|
||||
let paired_type = self.identifier.to_rust_paired();
|
||||
|
||||
let convertible = &self.derive_from_c_paried_rust(&paired_type);
|
||||
quote! {
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
*/
|
||||
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::{format_ident, ToTokens};
|
||||
use quote::{format_ident, quote, ToTokens};
|
||||
|
||||
use crate::parser::command_spec::Identifier;
|
||||
|
||||
|
@ -45,4 +45,18 @@ impl Identifier {
|
|||
pub fn to_c(&self) -> TokenStream2 {
|
||||
format_ident!("{}_c", self.name).to_token_stream()
|
||||
}
|
||||
|
||||
pub fn to_c_paired(&self) -> TokenStream2 {
|
||||
let path = &self.variant.to_c_path();
|
||||
let ident = &self.to_c();
|
||||
if path.is_empty() {
|
||||
quote! {
|
||||
crate :: #ident
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#path :: #ident
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,9 @@ impl Structure {
|
|||
|
||||
let contents: Vec<TokenStream2> = self.contents.iter().map(DocNamedType::to_c).collect();
|
||||
|
||||
// TODO: Convertible <2024-03-08>
|
||||
let paired_type = self.identifier.to_rust_paired();
|
||||
|
||||
let into_impl = &self.derive_from_c_paired_rust(&paired_type);
|
||||
quote! {
|
||||
#doc_comments
|
||||
#[allow(non_camel_case_types)]
|
||||
|
@ -45,6 +47,7 @@ impl Structure {
|
|||
pub struct #ident {
|
||||
#(#contents),*
|
||||
}
|
||||
#into_impl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ impl Enumeration {
|
|||
fn derive_from_paired(
|
||||
&self,
|
||||
ident_self: &TokenStream2,
|
||||
ident_paired: &TokenStream2,
|
||||
_ident_paired: &TokenStream2,
|
||||
paired_type: &TokenStream2,
|
||||
) -> TokenStream2 {
|
||||
let match_lines: TokenStream2 = self
|
||||
|
@ -38,7 +38,7 @@ impl Enumeration {
|
|||
.map(|state| {
|
||||
let name = Into::<Identifier>::into(state).to_rust();
|
||||
quote! {
|
||||
#ident_paired :: #name => Self :: #name,
|
||||
#paired_type :: #name => Self :: #name,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
|
|
@ -60,23 +60,26 @@ impl Structure {
|
|||
}
|
||||
|
||||
/// This function generates the `TryFrom<paired_type>` trait implementation for a given structure
|
||||
// was: `structure_into_impl`
|
||||
pub fn derive_into_impl(&self, paired_type: &TokenStream2) -> TokenStream2 {
|
||||
let ident = self.identifier.to_rust();
|
||||
|
||||
/// This function is more low-level, prefer to use the [`derive_from_c_paired_rust`] and
|
||||
/// [`derive_from_rust_paired_c`] functions instead.
|
||||
pub fn derive_from_paired(
|
||||
&self,
|
||||
ident_self: &TokenStream2,
|
||||
paired_type: &TokenStream2,
|
||||
) -> TokenStream2 {
|
||||
let try_into_fields: TokenStream2 = self
|
||||
.contents
|
||||
.iter()
|
||||
.map(|con| {
|
||||
let ident = &con.name.to_rust();
|
||||
.map(|content| {
|
||||
let name = content.name.to_rust();
|
||||
quote! {
|
||||
#ident: value.#ident.try_into()?,
|
||||
// #paired_type :: #name => Self :: #name,
|
||||
#name: value.#name.try_into()?,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
quote! {
|
||||
impl TryFrom<#paired_type> for #ident {
|
||||
impl TryFrom<#paired_type> for #ident_self {
|
||||
type Error = trixy::types::error::TypeConversionError;
|
||||
|
||||
fn try_from(value: #paired_type) -> Result<Self, Self::Error> {
|
||||
|
@ -87,4 +90,20 @@ impl Structure {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This function generates the `TryFrom<paired_type>` trait implementation for a given c
|
||||
/// structure
|
||||
pub fn derive_from_c_paired_rust(&self, paired_rust_type: &TokenStream2) -> TokenStream2 {
|
||||
let c_ident = self.identifier.to_c();
|
||||
|
||||
self.derive_from_paired(&c_ident, &paired_rust_type)
|
||||
}
|
||||
|
||||
/// This function generates the `TryFrom<paired_type>` trait implementation for a given rust
|
||||
/// structure
|
||||
pub fn derive_from_rust_paired_c(&self, paired_c_type: &TokenStream2) -> TokenStream2 {
|
||||
let rust_ident = self.identifier.to_rust();
|
||||
|
||||
self.derive_from_paired(&rust_ident, &paired_c_type)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,4 +48,22 @@ impl Identifier {
|
|||
#pascal_ident
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_rust_paired(&self) -> TokenStream2 {
|
||||
let path = &self
|
||||
.variant
|
||||
.to_rust_path()
|
||||
.expect("This should be generatable, when this function is called");
|
||||
|
||||
let ident = &self.to_rust();
|
||||
if path.is_empty() {
|
||||
quote! {
|
||||
crate :: #ident
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#path :: #ident
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,22 +34,11 @@ impl Structure {
|
|||
.collect();
|
||||
|
||||
let ident = &self.identifier.to_rust();
|
||||
let c_ident = {
|
||||
let path = &self.identifier.variant.to_c_path();
|
||||
let ident = &self.identifier.to_c();
|
||||
if path.is_empty() {
|
||||
quote! {
|
||||
crate :: #ident
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#path :: #ident
|
||||
}
|
||||
}
|
||||
};
|
||||
let contents: Vec<TokenStream2> = self.contents.iter().map(DocNamedType::to_rust).collect();
|
||||
|
||||
let c_ident = self.identifier.to_c_paired();
|
||||
let convertible = self.derive_convertible(&c_ident);
|
||||
let into_impl = self.derive_into_impl(&c_ident);
|
||||
let into_impl = self.derive_from_rust_paired_c(&c_ident);
|
||||
|
||||
quote! {
|
||||
#doc_comments
|
||||
|
|
Reference in New Issue