1
0
mirror of https://github.com/Sebekerga/native_api_1c.git synced 2025-06-16 23:47:43 +02:00

finished moving props to collectors

This commit is contained in:
Kozlov Maxim
2023-11-06 04:01:31 +06:00
parent 95aaef80bc
commit f281cfae37
11 changed files with 437 additions and 105 deletions

View File

@ -1,14 +1,10 @@
use common_generators::{param_ty_to_ffi_return, SettableTypes};
use proc_macro2::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};
use function_processing::{collectors::*, parse::parse_functions};
use props_processing::{generate::param_ty_to_ffi_set, parse::parse_props};
use utils::{
macros::{tkn_err, tkn_err_inner},
str_literal_token,
};
use props_processing::{collectors::*, parse::parse_props};
use utils::{macros::tkn_err, str_literal_token};
mod common_generators;
mod constants;
@ -51,78 +47,18 @@ fn build_impl_block(input: &DeriveInput) -> Result<proc_macro2::TokenStream, dar
let props = parse_props(struct_data)?;
let functions = parse_functions(struct_data)?;
let number_of_props = props.len();
let mut find_prop_body = quote! {};
let mut get_prop_name_body = quote! {};
let mut is_prop_readable_body = quote! {};
let mut is_prop_writable_body = quote! {};
let mut get_prop_val_body = quote! {};
let mut set_prop_val_body = quote! {};
for prop in &props {
let prop_ident = &prop.ident;
let name_literal = str_literal_token(&prop.name, struct_ident)?;
let name_ru_literal = str_literal_token(&prop.name_ru, struct_ident)?;
let readable = prop.readable;
let writable = prop.writable;
let prop_index = props.iter().position(|p| p.name == prop.name).unwrap();
find_prop_body = quote! {
#find_prop_body
if native_api_1c::native_api_1c_core::ffi::string_utils::os_string_nil(#name_literal) == name { return Some(#prop_index) };
if native_api_1c::native_api_1c_core::ffi::string_utils::os_string_nil(#name_ru_literal) == name { return Some(#prop_index) };
};
get_prop_name_body = quote! {
#get_prop_name_body
if num == #prop_index && alias == 0 { return Some(native_api_1c::native_api_1c_core::ffi::string_utils::os_string_nil(#name_literal).into()) };
if num == #prop_index { return Some(native_api_1c::native_api_1c_core::ffi::string_utils::os_string_nil(#name_ru_literal).into()) };
};
is_prop_readable_body = quote! {
#is_prop_readable_body
if num == #prop_index { return #readable };
};
is_prop_writable_body = quote! {
#is_prop_writable_body
if num == #prop_index { return #writable };
};
if readable {
let prop_settable: SettableTypes = (&prop.ty).try_into().map_err(|_| {
tkn_err_inner!(
"Incorrectly attempted to convert type to settable",
&prop.ident.span()
)
})?;
let ffi_set_tkn =
param_ty_to_ffi_return(&prop_settable, quote! { val }, quote! {self.#prop_ident});
get_prop_val_body = quote! {
#get_prop_val_body
if num == #prop_index {
#ffi_set_tkn;
return true;
};
};
};
if writable {
let prop_set_tkn = param_ty_to_ffi_set(&prop.ty, quote! { #prop_ident });
set_prop_val_body = quote! {
#set_prop_val_body
if num == #prop_index {
match val {
#prop_set_tkn
_ => return false,
}
return true;
};
};
}
}
let pi = props.iter().enumerate();
let prop_definitions = [
pi.clone().collect::<FindPropCollector>().release()?,
pi.clone().collect::<GetNPropsCollector>().release()?,
pi.clone().collect::<GetPropNameCollector>().release()?,
pi.clone().collect::<IsPropReadableCollector>().release()?,
pi.clone().collect::<IsPropWritableCollector>().release()?,
pi.clone().collect::<GetPropValCollector>().release()?,
pi.clone().collect::<SetPropValCollector>().release()?,
];
let fi = functions.iter().enumerate();
let func_definitions = [
fi.clone().collect::<FindMethodCollector>().release()?,
fi.clone().collect::<GetMethodNameCollector>().release()?,
@ -150,34 +86,10 @@ fn build_impl_block(input: &DeriveInput) -> Result<proc_macro2::TokenStream, dar
fn register_extension_as(&mut self) -> &[u16] {
&utf16_lit::utf16_null!(#add_in_name_literal)
}
fn get_n_props(&self) -> usize {
#number_of_props
}
fn find_prop(&self, name: &[u16]) -> Option<usize> {
#find_prop_body
None
}
fn get_prop_name(&self, num: usize, alias: usize) -> Option<Vec<u16>> {
#get_prop_name_body
None
}
fn get_prop_val(&self, num: usize, val: native_api_1c::native_api_1c_core::ffi::provided_types::ReturnValue) -> bool {
#get_prop_val_body
false
}
fn set_prop_val(&mut self, num: usize, val: &native_api_1c::native_api_1c_core::ffi::provided_types::ParamValue) -> bool {
#set_prop_val_body
false
}
fn is_prop_readable(&self, num: usize) -> bool {
#is_prop_readable_body
false
}
fn is_prop_writable(&self, num: usize) -> bool {
#is_prop_writable_body
false
}
#(#prop_definitions)*
#(#func_definitions)*
fn set_locale(&mut self, loc: &[u16]) {
}
fn set_user_interface_language_code(&mut self, lang: &[u16]) {

View File

@ -0,0 +1,55 @@
use proc_macro2::TokenStream;
use quote::quote;
use crate::props_processing::PropDesc;
use super::{empty_prop_collector_error, PropCollector};
pub struct FindPropCollector {
generated: Result<TokenStream, darling::Error>,
}
impl Default for FindPropCollector {
fn default() -> Self {
Self {
generated: Err(empty_prop_collector_error()),
}
}
}
impl<'a> FromIterator<(usize, &'a PropDesc)> for FindPropCollector {
fn from_iter<T: IntoIterator<Item = (usize, &'a PropDesc)>>(iter: T) -> Self {
let mut find_prop_body = TokenStream::new();
for (prop_index, prop_desc) in iter {
let name_literal = prop_desc.name_literal.clone();
let name_ru_literal = prop_desc.name_ru_literal.clone();
find_prop_body.extend(quote! {
if native_api_1c::native_api_1c_core::ffi::string_utils::os_string_nil(#name_literal) == name {
return Some(#prop_index)
};
if native_api_1c::native_api_1c_core::ffi::string_utils::os_string_nil(#name_ru_literal) == name {
return Some(#prop_index)
};
});
}
let _definition = quote! {
fn find_prop(&self, name: &[u16]) -> Option<usize> {
#find_prop_body
None
}
};
Self {
generated: Ok(_definition),
}
}
}
impl PropCollector<'_> for FindPropCollector {
fn release(self) -> Result<TokenStream, darling::Error> {
self.generated
}
}

View File

@ -0,0 +1,42 @@
use proc_macro2::TokenStream;
use quote::quote;
use crate::props_processing::PropDesc;
use super::{empty_prop_collector_error, PropCollector};
pub struct GetNPropsCollector {
generated: Result<TokenStream, darling::Error>,
}
impl Default for GetNPropsCollector {
fn default() -> Self {
Self {
generated: Err(empty_prop_collector_error()),
}
}
}
impl<'a> FromIterator<(usize, &'a PropDesc)> for GetNPropsCollector {
fn from_iter<T: IntoIterator<Item = (usize, &'a PropDesc)>>(iter: T) -> Self {
let mut _body = TokenStream::new();
let number_of_props = iter.into_iter().count();
let _definition = quote! {
fn get_n_props(&self) -> usize {
#number_of_props
}
};
Self {
generated: Ok(_definition),
}
}
}
impl PropCollector<'_> for GetNPropsCollector {
fn release(self) -> Result<TokenStream, darling::Error> {
self.generated
}
}

View File

@ -0,0 +1,51 @@
use proc_macro2::TokenStream;
use quote::quote;
use crate::props_processing::PropDesc;
use super::{empty_prop_collector_error, PropCollector};
pub struct GetPropNameCollector {
generated: Result<TokenStream, darling::Error>,
}
impl Default for GetPropNameCollector {
fn default() -> Self {
Self {
generated: Err(empty_prop_collector_error()),
}
}
}
impl<'a> FromIterator<(usize, &'a PropDesc)> for GetPropNameCollector {
fn from_iter<T: IntoIterator<Item = (usize, &'a PropDesc)>>(iter: T) -> Self {
let mut get_prop_name_body = TokenStream::new();
for (prop_index, prop_desc) in iter {
let name_literal = prop_desc.name_literal.clone();
let name_ru_literal = prop_desc.name_ru_literal.clone();
get_prop_name_body.extend(quote! {
if num == #prop_index && alias == 0 { return Some(native_api_1c::native_api_1c_core::ffi::string_utils::os_string_nil(#name_literal).into()) };
if num == #prop_index { return Some(native_api_1c::native_api_1c_core::ffi::string_utils::os_string_nil(#name_ru_literal).into()) };
});
}
let _definition = quote! {
fn get_prop_name(&self, num: usize, alias: usize) -> Option<Vec<u16>> {
#get_prop_name_body
None
}
};
Self {
generated: Ok(_definition),
}
}
}
impl PropCollector<'_> for GetPropNameCollector {
fn release(self) -> Result<TokenStream, darling::Error> {
self.generated
}
}

View File

@ -0,0 +1,74 @@
use proc_macro2::TokenStream;
use quote::quote;
use crate::{
common_generators::{param_ty_to_ffi_return, SettableTypes},
props_processing::PropDesc,
utils::macros::tkn_err_inner,
};
use super::{empty_prop_collector_error, PropCollector};
pub struct GetPropValCollector {
generated: Result<TokenStream, darling::Error>,
}
impl Default for GetPropValCollector {
fn default() -> Self {
Self {
generated: Err(empty_prop_collector_error()),
}
}
}
impl<'a> FromIterator<(usize, &'a PropDesc)> for GetPropValCollector {
fn from_iter<T: IntoIterator<Item = (usize, &'a PropDesc)>>(iter: T) -> Self {
let mut get_prop_val_body = TokenStream::new();
for (prop_index, prop_desc) in iter {
if !prop_desc.readable {
continue;
}
let prop_settable: SettableTypes = match (&prop_desc.ty).try_into().map_err(|_| {
tkn_err_inner!(
"Incorrectly attempted to convert type to settable",
&prop_desc.ident.span()
)
}) {
Ok(settable) => settable,
Err(err) => {
return Self {
generated: Err(err),
}
}
};
let prop_ident = &prop_desc.ident;
let ffi_set_tkn =
param_ty_to_ffi_return(&prop_settable, quote! { val }, quote! {self.#prop_ident});
get_prop_val_body.extend(quote! {
if num == #prop_index {
#ffi_set_tkn;
return true;
};
});
}
let _definition = quote! {
fn get_prop_val(&self, num: usize, val: native_api_1c::native_api_1c_core::ffi::provided_types::ReturnValue) -> bool {
#get_prop_val_body
false
}
};
Self {
generated: Ok(_definition),
}
}
}
impl PropCollector<'_> for GetPropValCollector {
fn release(self) -> Result<TokenStream, darling::Error> {
self.generated
}
}

View File

@ -0,0 +1,49 @@
use proc_macro2::TokenStream;
use quote::quote;
use crate::props_processing::PropDesc;
use super::{empty_prop_collector_error, PropCollector};
pub struct IsPropReadableCollector {
generated: Result<TokenStream, darling::Error>,
}
impl Default for IsPropReadableCollector {
fn default() -> Self {
Self {
generated: Err(empty_prop_collector_error()),
}
}
}
impl<'a> FromIterator<(usize, &'a PropDesc)> for IsPropReadableCollector {
fn from_iter<T: IntoIterator<Item = (usize, &'a PropDesc)>>(iter: T) -> Self {
let mut is_prop_readable_body = TokenStream::new();
for (prop_index, prop_desc) in iter {
let readable = prop_desc.readable;
is_prop_readable_body.extend(quote! {
if num == #prop_index { return #readable };
});
}
let _definition = quote! {
fn is_prop_readable(&self, num: usize) -> bool {
#is_prop_readable_body
false
}
};
Self {
generated: Ok(_definition),
}
}
}
impl PropCollector<'_> for IsPropReadableCollector {
fn release(self) -> Result<TokenStream, darling::Error> {
self.generated
}
}

View File

@ -0,0 +1,48 @@
use proc_macro2::TokenStream;
use quote::quote;
use crate::props_processing::PropDesc;
use super::{empty_prop_collector_error, PropCollector};
pub struct IsPropWritableCollector {
generated: Result<TokenStream, darling::Error>,
}
impl Default for IsPropWritableCollector {
fn default() -> Self {
Self {
generated: Err(empty_prop_collector_error()),
}
}
}
impl<'a> FromIterator<(usize, &'a PropDesc)> for IsPropWritableCollector {
fn from_iter<T: IntoIterator<Item = (usize, &'a PropDesc)>>(iter: T) -> Self {
let mut is_prop_writable_body = TokenStream::new();
for (prop_index, prop_desc) in iter {
let writable = prop_desc.writable;
is_prop_writable_body.extend(quote! {
if num == #prop_index { return #writable };
});
}
let _definition = quote! {
fn is_prop_writable(&self, num: usize) -> bool {
#is_prop_writable_body
false
}
};
Self {
generated: Ok(_definition),
}
}
}
impl PropCollector<'_> for IsPropWritableCollector {
fn release(self) -> Result<TokenStream, darling::Error> {
self.generated
}
}

View File

@ -0,0 +1,28 @@
use proc_macro2::TokenStream;
use super::PropDesc;
use crate::utils::macros::tkn_err_inner;
pub mod find_prop;
pub mod get_n_props;
pub mod get_prop_name;
pub mod get_prop_val;
pub mod is_prop_readable;
pub mod is_prop_writable;
pub mod set_prop_val;
pub use find_prop::FindPropCollector;
pub use get_n_props::GetNPropsCollector;
pub use get_prop_name::GetPropNameCollector;
pub use get_prop_val::GetPropValCollector;
pub use is_prop_readable::IsPropReadableCollector;
pub use is_prop_writable::IsPropWritableCollector;
pub use set_prop_val::SetPropValCollector;
pub trait PropCollector<'a>: FromIterator<(usize, &'a PropDesc)> + Default {
fn release(self) -> Result<TokenStream, darling::Error>;
}
pub fn empty_prop_collector_error() -> darling::Error {
tkn_err_inner!("No props found", &proc_macro2::Span::call_site())
}

View File

@ -0,0 +1,59 @@
use proc_macro2::TokenStream;
use quote::quote;
use crate::props_processing::{generate::param_ty_to_ffi_set, PropDesc};
use super::{empty_prop_collector_error, PropCollector};
pub struct SetPropValCollector {
generated: Result<TokenStream, darling::Error>,
}
impl Default for SetPropValCollector {
fn default() -> Self {
Self {
generated: Err(empty_prop_collector_error()),
}
}
}
impl<'a> FromIterator<(usize, &'a PropDesc)> for SetPropValCollector {
fn from_iter<T: IntoIterator<Item = (usize, &'a PropDesc)>>(iter: T) -> Self {
let mut set_prop_val_body = TokenStream::new();
for (prop_index, prop_desc) in iter {
if !prop_desc.writable {
continue;
}
let prop_ident = &prop_desc.ident;
let prop_set_tkn = param_ty_to_ffi_set(&prop_desc.ty, quote! { #prop_ident });
set_prop_val_body.extend(quote! {
if num == #prop_index {
match val {
#prop_set_tkn
_ => return false,
}
return true;
};
});
}
let _definition = quote! {
fn set_prop_val(&mut self, num: usize, val: &native_api_1c::native_api_1c_core::ffi::provided_types::ParamValue) -> bool {
#set_prop_val_body
false
}
};
Self {
generated: Ok(_definition),
}
}
}
impl PropCollector<'_> for SetPropValCollector {
fn release(self) -> Result<TokenStream, darling::Error> {
self.generated
}
}

View File

@ -1,18 +1,24 @@
use darling::FromMeta;
use proc_macro2::Ident;
use proc_macro2::{Ident, TokenStream};
use crate::{
common_generators::SettableTypes,
constants::{BLOB_TYPE, BOOL_TYPE, DATE_TYPE, F64_TYPE, I32_TYPE, STRING_TYPE},
};
pub mod collectors;
pub mod generate;
pub mod parse;
pub struct PropDesc {
pub ident: Ident,
pub name: String,
pub name_ru: String,
pub name_literal: TokenStream,
pub name_ru_literal: TokenStream,
pub readable: bool,
pub writable: bool,
pub ty: PropType,

View File

@ -1,7 +1,7 @@
use darling::{FromField, FromMeta};
use syn::{Attribute, DataStruct};
use crate::utils::ident_option_to_darling_err;
use crate::utils::{ident_option_to_darling_err, str_literal_token};
use super::{PropDesc, PropType};
@ -29,10 +29,18 @@ impl FromField for PropDesc {
let prop_meta = PropMeta::from_meta(&add_in_prop_attr.meta)?;
let name_literal = str_literal_token(&prop_meta.name, field_ident)?;
let name_ru_literal = str_literal_token(&prop_meta.name_ru, field_ident)?;
Ok(PropDesc {
ident: field_ident.clone(),
name: prop_meta.name,
name_ru: prop_meta.name_ru,
name_literal,
name_ru_literal,
readable: prop_meta.readable.is_some(),
writable: prop_meta.writable.is_some(),
ty: prop_meta.ty,