From 700c049f64b66f424cda5da3021dfce4462655ca Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Tue, 21 Jul 2026 05:49:00 +0800 Subject: feat(core): add generic parameter `C` to `StructuralData` trait Make `StructuralData` and `StructuralDataSealed` generic over a program collector type to bypass the orphan rule for `group_structural!`. This enables external types to implement `StructuralData` without violating coherence. --- mingling_core/src/lib.rs | 8 +++++++- mingling_core/src/renderer/structural.rs | 16 ++++++++++------ mingling_core/src/renderer/structural/structural_data.rs | 8 +++++++- 3 files changed, 24 insertions(+), 8 deletions(-) (limited to 'mingling_core/src') diff --git a/mingling_core/src/lib.rs b/mingling_core/src/lib.rs index 2cb24b9..31476c9 100644 --- a/mingling_core/src/lib.rs +++ b/mingling_core/src/lib.rs @@ -90,8 +90,14 @@ pub mod setup { /// Private API — not intended for direct use. #[doc(hidden)] pub mod __private { + use crate::ProgramCollect; + /// Sealed trait for `StructuralData` — only implementable via derive macro. - pub trait StructuralDataSealed {} + pub trait StructuralDataSealed + where + C: ProgramCollect, + { + } /// Re-export so the derive macro can reference the trait without /// conflicting with the derive macro name at `::mingling::StructuralData`. diff --git a/mingling_core/src/renderer/structural.rs b/mingling_core/src/renderer/structural.rs index 30255aa..0449e72 100644 --- a/mingling_core/src/renderer/structural.rs +++ b/mingling_core/src/renderer/structural.rs @@ -1,5 +1,5 @@ use crate::{ - RenderResult, StructuralRendererSetting, + ProgramCollect, RenderResult, StructuralRendererSetting, renderer::structural::error::StructuralRendererSerializeError, }; use serde::Serialize; @@ -24,11 +24,15 @@ impl StructuralRenderer { /// /// Returns `Err(StructuralRendererSerializeError)` if serialization fails. #[allow(unused_variables)] - pub fn render( + pub fn render( data: &T, setting: &StructuralRendererSetting, r: &mut RenderResult, - ) -> Result<(), StructuralRendererSerializeError> { + ) -> Result<(), StructuralRendererSerializeError> + where + T: StructuralData + Send, + C: ProgramCollect, + { match setting { StructuralRendererSetting::Disable => Ok(()), #[cfg(feature = "json_serde_fmt")] @@ -148,7 +152,7 @@ impl StructuralRenderer { #[cfg(test)] mod tests { use super::*; - use crate::RenderResult; + use crate::{MockProgramCollect, RenderResult}; use serde::Serialize; #[derive(Debug, Clone, PartialEq, Serialize)] @@ -157,8 +161,8 @@ mod tests { value: i32, } - impl crate::__private::StructuralDataSealed for TestData {} - impl StructuralData for TestData {} + impl crate::__private::StructuralDataSealed for TestData {} + impl StructuralData for TestData {} fn test_data() -> TestData { TestData { diff --git a/mingling_core/src/renderer/structural/structural_data.rs b/mingling_core/src/renderer/structural/structural_data.rs index 1cafac3..583808c 100644 --- a/mingling_core/src/renderer/structural/structural_data.rs +++ b/mingling_core/src/renderer/structural/structural_data.rs @@ -1,5 +1,7 @@ use serde::Serialize; +use crate::ProgramCollect; + /// Marker trait for types that support structured output (JSON / YAML / TOML / RON). /// /// This trait is a **supertrait** of `serde::Serialize` and is sealed via @@ -12,4 +14,8 @@ use serde::Serialize; /// These entry points also register the type in the global `STRUCTURED_TYPES` /// registry, which is required for the `structural_render` match arm to be generated. #[doc(hidden)] -pub trait StructuralData: Serialize + crate::__private::StructuralDataSealed {} +pub trait StructuralData: Serialize + crate::__private::StructuralDataSealed +where + C: ProgramCollect, +{ +} -- cgit