diff --git a/crates/cgp-error/src/traits/can_raise_error.rs b/crates/cgp-error/src/traits/can_raise_error.rs index 835592af..4fbbd1a8 100644 --- a/crates/cgp-error/src/traits/can_raise_error.rs +++ b/crates/cgp-error/src/traits/can_raise_error.rs @@ -1,4 +1,5 @@ use cgp_component::*; +use cgp_field::types::*; use cgp_macro::cgp_component; use crate::traits::has_error_type::HasErrorType; @@ -11,6 +12,7 @@ use crate::traits::has_error_type::HasErrorType; provider: ErrorRaiser, derive_delegate: UseDelegate, }] +#[use_namespace(cgp.core.error)] pub trait CanRaiseError: HasErrorType { fn raise_error(error: SourceError) -> Self::Error; } diff --git a/crates/cgp-field/src/types/field.rs b/crates/cgp-field/src/types/field.rs index 32073a44..ca4ddca2 100644 --- a/crates/cgp-field/src/types/field.rs +++ b/crates/cgp-field/src/types/field.rs @@ -84,11 +84,4 @@ where } } -impl Eq for Field -where - Value: Eq, -{ - fn assert_receiver_is_total_eq(&self) { - self.value.assert_receiver_is_total_eq() - } -} +impl Eq for Field where Value: Eq {} diff --git a/crates/cgp-macro-lib/src/parse/delegate_components.rs b/crates/cgp-macro-lib/src/parse/delegate_components.rs index d5a98895..9df0c55e 100644 --- a/crates/cgp-macro-lib/src/parse/delegate_components.rs +++ b/crates/cgp-macro-lib/src/parse/delegate_components.rs @@ -1,12 +1,12 @@ use core::iter; -use proc_macro2::TokenStream; +use proc_macro2::{Span, TokenStream}; use quote::{ToTokens, TokenStreamExt, quote}; use syn::parse::discouraged::Speculative; use syn::parse::{Parse, ParseStream}; use syn::punctuated::Punctuated; -use syn::token::{At, Bracket, Colon, Comma, Gt, Lt, Pound, RArrow}; -use syn::{Attribute, Error, Generics, Ident, Token, Type, braced, bracketed, parse_quote}; +use syn::token::{At, Bracket, Colon, Comma, Gt, Lt, Pound, RArrow, Semi}; +use syn::{Attribute, Error, Generics, Ident, Token, Type, braced, bracketed, parse_quote, parse2}; use crate::parse::{ComponentPaths, ImplGenerics, SimpleType, TypeGenerics}; @@ -99,22 +99,68 @@ impl Parse for DelegateComponents { let target_type: Type = input.parse()?; - let delegate_entries = { - let content; - braced!(content in input); - Punctuated::parse_terminated(&content)? - }; + let content; + braced!(content in input); + + let meta_entries = parse_meta_delegate_entries(&content, &target_type)?; + + let delegate_entries: Punctuated, Comma> = + Punctuated::parse_terminated(&content)?; + + let entries = meta_entries.into_iter().chain(delegate_entries).collect(); Ok(Self { attributes, new_struct, target_type, target_generics, - entries: delegate_entries, + entries, }) } } +pub fn parse_meta_delegate_entries( + input: ParseStream, + target_type: &Type, +) -> syn::Result>> { + let mut entries = Vec::new(); + + while input.peek(Ident) { + let fork = input.fork(); + let keyword: Ident = fork.parse()?; + + if keyword == "open" { + input.advance_to(&fork); + + let components: Punctuated = Punctuated::parse_separated_nonempty(input)?; + let _: Semi = input.parse()?; + + for component in components { + let value = DelegateValue::Type(parse2( + quote!(RedirectLookup<#target_type, PathCons<#component, PathNil>>), + )?); + + let key = DelegateKey { + ty: component, + generics: Default::default(), + }; + + let entry = DelegateEntry { + keys: Punctuated::from_iter([key]), + mode: DelegateMode::Provider(Colon(Span::call_site())), + value, + }; + + entries.push(entry) + } + } else { + break; + } + } + + Ok(entries) +} + impl Parse for DelegateEntry { fn parse(input: ParseStream) -> syn::Result { let components = if input.peek(Bracket) { diff --git a/crates/cgp-tests/src/namespaces/extend.rs b/crates/cgp-tests/src/namespaces/extend.rs index 13490859..3d19b6a2 100644 --- a/crates/cgp-tests/src/namespaces/extend.rs +++ b/crates/cgp-tests/src/namespaces/extend.rs @@ -16,7 +16,15 @@ where type Provider = Provider; } -impl ExtendedNamespace for ErrorRaiserComponent { +impl ExtendedNamespace + for PathCons< + Symbol!("cgp"), + PathCons< + Symbol!("core"), + PathCons>>, + >, + > +{ type Provider = RedirectLookup< Components, PathCons>, diff --git a/crates/cgp-tests/tests/namespace_tests/experiments.rs b/crates/cgp-tests/tests/namespace_tests/extend_namespace.rs similarity index 100% rename from crates/cgp-tests/tests/namespace_tests/experiments.rs rename to crates/cgp-tests/tests/namespace_tests/extend_namespace.rs diff --git a/crates/cgp-tests/tests/namespace_tests/mod.rs b/crates/cgp-tests/tests/namespace_tests/mod.rs index 2a24debe..05efb2a4 100644 --- a/crates/cgp-tests/tests/namespace_tests/mod.rs +++ b/crates/cgp-tests/tests/namespace_tests/mod.rs @@ -1,3 +1,4 @@ -pub mod experiments; +pub mod extend_namespace; +pub mod open; pub mod redirect; pub mod use_namespace; diff --git a/crates/cgp-tests/tests/namespace_tests/open.rs b/crates/cgp-tests/tests/namespace_tests/open.rs new file mode 100644 index 00000000..fff4e71b --- /dev/null +++ b/crates/cgp-tests/tests/namespace_tests/open.rs @@ -0,0 +1,23 @@ +use cgp::core::error::{ErrorRaiserComponent, ErrorTypeProviderComponent}; +use cgp::extra::error::ReturnError; +use cgp::prelude::*; + +pub struct App; + +delegate_components! { + App { + open ErrorRaiserComponent; + + ErrorTypeProviderComponent: + UseType, + @ErrorRaiserComponent.String: + ReturnError, + } +} + +check_components! { + App { + ErrorRaiserComponent: + String, + } +} diff --git a/crates/cgp-tests/tests/namespace_tests/use_namespace.rs b/crates/cgp-tests/tests/namespace_tests/use_namespace.rs index ada8fe0e..6b8e16c3 100644 --- a/crates/cgp-tests/tests/namespace_tests/use_namespace.rs +++ b/crates/cgp-tests/tests/namespace_tests/use_namespace.rs @@ -1,4 +1,5 @@ -use cgp::core::error::ErrorTypeProviderComponent; +use cgp::core::error::{ErrorRaiserComponent, ErrorTypeProviderComponent}; +use cgp::extra::error::ReturnError; use cgp::prelude::*; pub struct MyComponents; @@ -16,5 +17,13 @@ delegate_components! { App { @cgp.core.error.ErrorTypeProviderComponent: UseType, + @cgp.core.error.ErrorRaiserComponent.String: + ReturnError, + } +} + +check_components! { + App { + ErrorRaiserComponent: String, } }