Skip to content

Commit b960a0d

Browse files
committed
Allow non-static types to implement the schema
1 parent 244cea9 commit b960a0d

File tree

4 files changed

+45
-13
lines changed

4 files changed

+45
-13
lines changed

packages/cw-schema/src/default_impls.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,19 @@ impl Schemaifier for () {
1414
}
1515
}
1616

17+
impl Schemaifier for str {
18+
fn visit_schema(visitor: &mut crate::SchemaVisitor) -> crate::DefinitionReference {
19+
visitor.insert(
20+
Self::id(),
21+
Node {
22+
name: Cow::Borrowed("str"),
23+
description: None,
24+
value: NodeType::String,
25+
},
26+
)
27+
}
28+
}
29+
1730
impl Schemaifier for String {
1831
fn visit_schema(visitor: &mut crate::SchemaVisitor) -> crate::DefinitionReference {
1932
visitor.insert(
@@ -163,3 +176,12 @@ where
163176
visitor.insert(Self::id(), node)
164177
}
165178
}
179+
180+
impl<T> Schemaifier for &T
181+
where
182+
T: Schemaifier + ?Sized,
183+
{
184+
fn visit_schema(visitor: &mut crate::SchemaVisitor) -> crate::DefinitionReference {
185+
T::visit_schema(visitor)
186+
}
187+
}

packages/cw-schema/src/lib.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,14 +145,20 @@ pub enum Schema {
145145
}
146146

147147
#[derive(Hash, PartialEq, Eq)]
148-
pub struct Identifier(core::any::TypeId);
148+
pub struct Identifier(usize);
149149

150150
impl Identifier {
151151
pub fn of<T>() -> Self
152152
where
153-
T: ?Sized + 'static,
153+
T: ?Sized,
154154
{
155-
Self(core::any::TypeId::of::<T>())
155+
// Don't do this at home. I'm a professional.
156+
#[inline]
157+
fn type_id_of<T: ?Sized>() -> usize {
158+
type_id_of::<T> as usize
159+
}
160+
161+
Self(type_id_of::<T>())
156162
}
157163
}
158164

@@ -182,7 +188,7 @@ impl SchemaVisitor {
182188
}
183189
}
184190

185-
pub trait Schemaifier: 'static {
191+
pub trait Schemaifier {
186192
#[doc(hidden)]
187193
fn id() -> Identifier {
188194
Identifier::of::<Self>()
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#![allow(dead_code)]
2+
3+
use cw_schema::Schemaifier;
4+
5+
#[derive(Schemaifier)]
6+
struct NonStatic<'a> {
7+
test: &'a str,
8+
}

packages/schema-derive/src/query_responses.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ pub fn query_responses_derive_impl(input: ItemEnum) -> syn::Result<ItemImpl> {
2121
let subquery_calls = input
2222
.variants
2323
.iter()
24-
.map(|variant| parse_subquery(&ctx, variant.clone(), SchemaBackend::JsonSchema))
24+
.map(|variant| parse_subquery(&ctx, variant, SchemaBackend::JsonSchema))
2525
.collect::<syn::Result<Vec<_>>>()?;
2626

2727
let subquery_calls_cw = input
2828
.variants
29-
.into_iter()
29+
.iter()
3030
.map(|variant| parse_subquery(&ctx, variant, SchemaBackend::CwSchema))
3131
.collect::<syn::Result<Vec<_>>>()?;
3232

@@ -67,8 +67,6 @@ pub fn query_responses_derive_impl(input: ItemEnum) -> syn::Result<ItemImpl> {
6767
.map(|variant| parse_query(&ctx, variant, SchemaBackend::JsonSchema))
6868
.collect::<syn::Result<Vec<_>>>()?;
6969

70-
let mut queries: Vec<_> = mappings.clone().into_iter().map(|(q, _)| q).collect();
71-
queries.sort();
7270
let mappings = mappings.into_iter().map(parse_tuple);
7371

7472
let cw_mappings = input
@@ -77,8 +75,6 @@ pub fn query_responses_derive_impl(input: ItemEnum) -> syn::Result<ItemImpl> {
7775
.map(|variant| parse_query(&ctx, variant, SchemaBackend::CwSchema))
7876
.collect::<syn::Result<Vec<_>>>()?;
7977

80-
let mut cw_queries: Vec<_> = cw_mappings.clone().into_iter().map(|(q, _)| q).collect();
81-
cw_queries.sort();
8278
let cw_mappings = cw_mappings.into_iter().map(parse_tuple);
8379

8480
// Handle generics if the type has any
@@ -159,16 +155,16 @@ fn parse_query(
159155
}
160156

161157
/// Extract the nested query -> response mapping out of an enum variant.
162-
fn parse_subquery(ctx: &Context, v: Variant, schema_backend: SchemaBackend) -> syn::Result<Expr> {
158+
fn parse_subquery(ctx: &Context, v: &Variant, schema_backend: SchemaBackend) -> syn::Result<Expr> {
163159
let crate_name = &ctx.crate_name;
164160
let submsg = match v.fields {
165161
syn::Fields::Named(_) => bail!(v, "a struct variant is not a valid subquery"),
166-
syn::Fields::Unnamed(fields) => {
162+
syn::Fields::Unnamed(ref fields) => {
167163
if fields.unnamed.len() != 1 {
168164
bail!(fields, "invalid number of subquery parameters");
169165
}
170166

171-
fields.unnamed[0].ty.clone()
167+
&fields.unnamed[0].ty
172168
}
173169
syn::Fields::Unit => bail!(v, "a unit variant is not a valid subquery"),
174170
};

0 commit comments

Comments
 (0)