Skip to content

Commit b217f8c

Browse files
authored
Merge pull request #116 from dev-five-git/schema-type-has-one
Fix schema_type has_one
2 parents c3c316a + 25780ad commit b217f8c

File tree

10 files changed

+231
-3
lines changed

10 files changed

+231
-3
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"changes":{"Cargo.toml":"Patch"},"note":"Fix schema_type has_one","date":"2026-04-01T14:13:09.811093500Z"}

crates/vespera_macro/src/schema_macro/type_utils.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,19 @@ pub const PRIMITIVE_TYPE_NAMES: &[&str] = &[
1616
"f64", "bool", "String", "Decimal",
1717
];
1818

19-
/// Normalize a `TokenStream` or `Type` to a compact string by removing spaces.
19+
/// Normalize a `TokenStream` or `Type` to a compact string by removing all whitespace.
2020
///
2121
/// This replaces the common `.to_string().replace(' ', "")` pattern used throughout
2222
/// the codebase to produce deterministic path strings for comparison and cache keys.
23+
///
24+
/// Removes spaces, newlines, and carriage returns — `proc_macro2`'s `Display` impl
25+
/// may insert newlines when token sequences exceed an internal line-length threshold,
26+
/// which would break substring checks like `contains("HasOne<")`.
2327
#[inline]
2428
pub fn normalize_token_str(displayable: &impl std::fmt::Display) -> String {
2529
let s = displayable.to_string();
26-
if s.contains(' ') {
27-
s.replace(' ', "")
30+
if s.contains(|c: char| c.is_ascii_whitespace()) {
31+
s.replace(|c: char| c.is_ascii_whitespace(), "")
2832
} else {
2933
s
3034
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/dev-five-git/vespertide/refs/heads/main/schemas/model.schema.json",
3+
"name": "single",
4+
"columns": [
5+
{
6+
"name": "username",
7+
"type": { "kind": "varchar", "length": 32 },
8+
"nullable": false,
9+
"primary_key": true
10+
}
11+
]
12+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/dev-five-git/vespertide/refs/heads/main/schemas/model.schema.json",
3+
"name": "single_rel",
4+
"columns": [
5+
{
6+
"name": "username",
7+
"type": { "kind": "varchar", "length": 32 },
8+
"nullable": false,
9+
"primary_key": true,
10+
"foreign_key": {
11+
"ref_table": "single",
12+
"ref_columns": ["username"],
13+
"on_delete": "cascade"
14+
}
15+
}
16+
]
17+
}

examples/axum-example/openapi.json

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3467,6 +3467,60 @@
34673467
"createdAt"
34683468
]
34693469
},
3470+
"SingleRelSchema": {
3471+
"type": "object",
3472+
"properties": {
3473+
"single": {
3474+
"$ref": "#/components/schemas/SingleRelSchema_Single"
3475+
},
3476+
"username": {
3477+
"type": "string",
3478+
"default": ""
3479+
}
3480+
},
3481+
"required": [
3482+
"username",
3483+
"single"
3484+
]
3485+
},
3486+
"SingleRelSchema_Single": {
3487+
"type": "object",
3488+
"properties": {
3489+
"username": {
3490+
"type": "string"
3491+
}
3492+
},
3493+
"required": [
3494+
"username"
3495+
]
3496+
},
3497+
"SingleSchema": {
3498+
"type": "object",
3499+
"properties": {
3500+
"singleRel": {
3501+
"$ref": "#/components/schemas/SingleSchema_SingleRel",
3502+
"nullable": true
3503+
},
3504+
"username": {
3505+
"type": "string",
3506+
"default": ""
3507+
}
3508+
},
3509+
"required": [
3510+
"username"
3511+
]
3512+
},
3513+
"SingleSchema_SingleRel": {
3514+
"type": "object",
3515+
"properties": {
3516+
"username": {
3517+
"type": "string"
3518+
}
3519+
},
3520+
"required": [
3521+
"username"
3522+
]
3523+
},
34703524
"SkipResponse": {
34713525
"type": "object",
34723526
"properties": {
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
pub mod config;
22
pub mod memo;
33
pub mod memo_comment;
4+
pub mod single;
5+
pub mod single_rel;
46
pub mod user;
57
pub mod uuid_item;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![allow(dead_code)]
2+
use sea_orm::entity::prelude::*;
3+
4+
#[sea_orm::model]
5+
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
6+
#[sea_orm(table_name = "single")]
7+
pub struct Model {
8+
#[sea_orm(primary_key)]
9+
pub username: String,
10+
#[sea_orm(has_one)]
11+
pub single_rel: HasOne<crate::models::single_rel::Entity>,
12+
}
13+
14+
vespera::schema_type!(Schema from Model, name = "SingleSchema");
15+
impl ActiveModelBehavior for ActiveModel {}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![allow(dead_code)]
2+
use sea_orm::entity::prelude::*;
3+
4+
#[sea_orm::model]
5+
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
6+
#[sea_orm(table_name = "single_rel")]
7+
pub struct Model {
8+
#[sea_orm(primary_key)]
9+
pub username: String,
10+
#[sea_orm(belongs_to, from = "username", to = "username")]
11+
pub single: HasOne<crate::models::single::Entity>,
12+
}
13+
14+
vespera::schema_type!(Schema from Model, name = "SingleRelSchema");
15+
impl ActiveModelBehavior for ActiveModel {}

examples/axum-example/tests/snapshots/integration_test__openapi.snap

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3471,6 +3471,60 @@ expression: "std::fs::read_to_string(\"openapi.json\").unwrap()"
34713471
"createdAt"
34723472
]
34733473
},
3474+
"SingleRelSchema": {
3475+
"type": "object",
3476+
"properties": {
3477+
"single": {
3478+
"$ref": "#/components/schemas/SingleRelSchema_Single"
3479+
},
3480+
"username": {
3481+
"type": "string",
3482+
"default": ""
3483+
}
3484+
},
3485+
"required": [
3486+
"username",
3487+
"single"
3488+
]
3489+
},
3490+
"SingleRelSchema_Single": {
3491+
"type": "object",
3492+
"properties": {
3493+
"username": {
3494+
"type": "string"
3495+
}
3496+
},
3497+
"required": [
3498+
"username"
3499+
]
3500+
},
3501+
"SingleSchema": {
3502+
"type": "object",
3503+
"properties": {
3504+
"singleRel": {
3505+
"$ref": "#/components/schemas/SingleSchema_SingleRel",
3506+
"nullable": true
3507+
},
3508+
"username": {
3509+
"type": "string",
3510+
"default": ""
3511+
}
3512+
},
3513+
"required": [
3514+
"username"
3515+
]
3516+
},
3517+
"SingleSchema_SingleRel": {
3518+
"type": "object",
3519+
"properties": {
3520+
"username": {
3521+
"type": "string"
3522+
}
3523+
},
3524+
"required": [
3525+
"username"
3526+
]
3527+
},
34743528
"SkipResponse": {
34753529
"type": "object",
34763530
"properties": {

openapi.json

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3467,6 +3467,60 @@
34673467
"createdAt"
34683468
]
34693469
},
3470+
"SingleRelSchema": {
3471+
"type": "object",
3472+
"properties": {
3473+
"single": {
3474+
"$ref": "#/components/schemas/SingleRelSchema_Single"
3475+
},
3476+
"username": {
3477+
"type": "string",
3478+
"default": ""
3479+
}
3480+
},
3481+
"required": [
3482+
"username",
3483+
"single"
3484+
]
3485+
},
3486+
"SingleRelSchema_Single": {
3487+
"type": "object",
3488+
"properties": {
3489+
"username": {
3490+
"type": "string"
3491+
}
3492+
},
3493+
"required": [
3494+
"username"
3495+
]
3496+
},
3497+
"SingleSchema": {
3498+
"type": "object",
3499+
"properties": {
3500+
"singleRel": {
3501+
"$ref": "#/components/schemas/SingleSchema_SingleRel",
3502+
"nullable": true
3503+
},
3504+
"username": {
3505+
"type": "string",
3506+
"default": ""
3507+
}
3508+
},
3509+
"required": [
3510+
"username"
3511+
]
3512+
},
3513+
"SingleSchema_SingleRel": {
3514+
"type": "object",
3515+
"properties": {
3516+
"username": {
3517+
"type": "string"
3518+
}
3519+
},
3520+
"required": [
3521+
"username"
3522+
]
3523+
},
34703524
"SkipResponse": {
34713525
"type": "object",
34723526
"properties": {

0 commit comments

Comments
 (0)