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();
|
.collect();
|
||||||
|
|
||||||
let states: Vec<TokenStream2> = self.states.iter().map(DocIdentifier::to_rust).collect();
|
let states: Vec<TokenStream2> = self.states.iter().map(DocIdentifier::to_rust).collect();
|
||||||
let paired_type = {
|
let paired_type = self.identifier.to_rust_paired();
|
||||||
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 convertible = &self.derive_from_c_paried_rust(&paired_type);
|
let convertible = &self.derive_from_c_paried_rust(&paired_type);
|
||||||
quote! {
|
quote! {
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use proc_macro2::TokenStream as TokenStream2;
|
use proc_macro2::TokenStream as TokenStream2;
|
||||||
use quote::{format_ident, ToTokens};
|
use quote::{format_ident, quote, ToTokens};
|
||||||
|
|
||||||
use crate::parser::command_spec::Identifier;
|
use crate::parser::command_spec::Identifier;
|
||||||
|
|
||||||
|
@ -45,4 +45,18 @@ impl Identifier {
|
||||||
pub fn to_c(&self) -> TokenStream2 {
|
pub fn to_c(&self) -> TokenStream2 {
|
||||||
format_ident!("{}_c", self.name).to_token_stream()
|
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();
|
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! {
|
quote! {
|
||||||
#doc_comments
|
#doc_comments
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
|
@ -45,6 +47,7 @@ impl Structure {
|
||||||
pub struct #ident {
|
pub struct #ident {
|
||||||
#(#contents),*
|
#(#contents),*
|
||||||
}
|
}
|
||||||
|
#into_impl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ impl Enumeration {
|
||||||
fn derive_from_paired(
|
fn derive_from_paired(
|
||||||
&self,
|
&self,
|
||||||
ident_self: &TokenStream2,
|
ident_self: &TokenStream2,
|
||||||
ident_paired: &TokenStream2,
|
_ident_paired: &TokenStream2,
|
||||||
paired_type: &TokenStream2,
|
paired_type: &TokenStream2,
|
||||||
) -> TokenStream2 {
|
) -> TokenStream2 {
|
||||||
let match_lines: TokenStream2 = self
|
let match_lines: TokenStream2 = self
|
||||||
|
@ -38,7 +38,7 @@ impl Enumeration {
|
||||||
.map(|state| {
|
.map(|state| {
|
||||||
let name = Into::<Identifier>::into(state).to_rust();
|
let name = Into::<Identifier>::into(state).to_rust();
|
||||||
quote! {
|
quote! {
|
||||||
#ident_paired :: #name => Self :: #name,
|
#paired_type :: #name => Self :: #name,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
|
@ -60,23 +60,26 @@ impl Structure {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function generates the `TryFrom<paired_type>` trait implementation for a given structure
|
/// This function generates the `TryFrom<paired_type>` trait implementation for a given structure
|
||||||
// was: `structure_into_impl`
|
/// This function is more low-level, prefer to use the [`derive_from_c_paired_rust`] and
|
||||||
pub fn derive_into_impl(&self, paired_type: &TokenStream2) -> TokenStream2 {
|
/// [`derive_from_rust_paired_c`] functions instead.
|
||||||
let ident = self.identifier.to_rust();
|
pub fn derive_from_paired(
|
||||||
|
&self,
|
||||||
|
ident_self: &TokenStream2,
|
||||||
|
paired_type: &TokenStream2,
|
||||||
|
) -> TokenStream2 {
|
||||||
let try_into_fields: TokenStream2 = self
|
let try_into_fields: TokenStream2 = self
|
||||||
.contents
|
.contents
|
||||||
.iter()
|
.iter()
|
||||||
.map(|con| {
|
.map(|content| {
|
||||||
let ident = &con.name.to_rust();
|
let name = content.name.to_rust();
|
||||||
quote! {
|
quote! {
|
||||||
#ident: value.#ident.try_into()?,
|
// #paired_type :: #name => Self :: #name,
|
||||||
|
#name: value.#name.try_into()?,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
impl TryFrom<#paired_type> for #ident {
|
impl TryFrom<#paired_type> for #ident_self {
|
||||||
type Error = trixy::types::error::TypeConversionError;
|
type Error = trixy::types::error::TypeConversionError;
|
||||||
|
|
||||||
fn try_from(value: #paired_type) -> Result<Self, Self::Error> {
|
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
|
#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();
|
.collect();
|
||||||
|
|
||||||
let ident = &self.identifier.to_rust();
|
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 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 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! {
|
quote! {
|
||||||
#doc_comments
|
#doc_comments
|
||||||
|
|
Reference in New Issue