Skip to content

Commit

Permalink
feat: add max/min for 8, 16 and 128 bit integers (#523)
Browse files Browse the repository at this point in the history
Signed-off-by: Tiago Castro <[email protected]>
  • Loading branch information
tiagolobocastro authored Jun 28, 2024
1 parent c7e9575 commit 135096f
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 11 deletions.
74 changes: 68 additions & 6 deletions core/src/v2/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ pub trait TypedData {
fn format() -> Option<DataTypeFormat> {
None
}

fn max() -> Option<f32> {
None
}

fn min() -> Option<f32> {
None
}
}

macro_rules! impl_type_simple {
Expand All @@ -150,6 +158,22 @@ macro_rules! impl_type_simple {
}
}
};
($ty:ty, $dt:expr, $df:expr, $min:expr, $max:expr) => {
impl TypedData for $ty {
fn data_type() -> DataType {
$dt
}
fn format() -> Option<DataTypeFormat> {
Some($df)
}
fn max() -> Option<f32> {
Some($max)
}
fn min() -> Option<f32> {
Some($min)
}
}
};
}

impl<'a> TypedData for &'a str {
Expand All @@ -174,17 +198,53 @@ impl_type_simple!(PathBuf, DataType::String);
impl_type_simple!(bool, DataType::Boolean);
impl_type_simple!(f32, DataType::Number, DataTypeFormat::Float);
impl_type_simple!(f64, DataType::Number, DataTypeFormat::Double);
impl_type_simple!(i8, DataType::Integer, DataTypeFormat::Int32);
impl_type_simple!(i16, DataType::Integer, DataTypeFormat::Int32);
impl_type_simple!(
i8,
DataType::Integer,
DataTypeFormat::Int32,
i8::MIN as f32,
i8::MAX as f32
);
impl_type_simple!(
i16,
DataType::Integer,
DataTypeFormat::Int32,
i16::MIN as f32,
i16::MAX as f32
);
impl_type_simple!(i32, DataType::Integer, DataTypeFormat::Int32);
impl_type_simple!(u8, DataType::Integer, DataTypeFormat::Int32);
impl_type_simple!(u16, DataType::Integer, DataTypeFormat::Int32);
impl_type_simple!(
u8,
DataType::Integer,
DataTypeFormat::Int32,
u8::MIN as f32,
u8::MAX as f32
);
impl_type_simple!(
u16,
DataType::Integer,
DataTypeFormat::Int32,
u16::MIN as f32,
u16::MAX as f32
);
impl_type_simple!(u32, DataType::Integer, DataTypeFormat::Int32);
impl_type_simple!(i64, DataType::Integer, DataTypeFormat::Int64);
impl_type_simple!(i128, DataType::Integer, DataTypeFormat::Int64);
impl_type_simple!(
i128,
DataType::Integer,
DataTypeFormat::Int64,
i128::MIN as f32,
i128::MAX as f32
);
impl_type_simple!(isize, DataType::Integer, DataTypeFormat::Int64);
impl_type_simple!(u64, DataType::Integer, DataTypeFormat::Int64);
impl_type_simple!(u128, DataType::Integer, DataTypeFormat::Int64);
impl_type_simple!(
u128,
DataType::Integer,
DataTypeFormat::Int64,
u128::MIN as f32,
u128::MAX as f32
);
impl_type_simple!(usize, DataType::Integer, DataTypeFormat::Int64);

#[cfg(feature = "actix-multipart")]
Expand Down Expand Up @@ -333,6 +393,8 @@ impl<T: TypedData> Apiv2Schema for T {
DefaultSchemaRaw {
data_type: Some(T::data_type()),
format: T::format(),
maximum: T::max(),
minimum: T::min(),
..Default::default()
}
}
Expand Down
8 changes: 8 additions & 0 deletions macros/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,14 @@ fn schema_fields(name: &Ident, is_ref: bool) -> proc_macro2::TokenStream {
#[serde(skip_serializing_if = "Option::is_none")]
pub format: Option<paperclip::v2::models::DataTypeFormat>,
));
gen.extend(quote!(
#[serde(skip_serializing_if = "Option::is_none")]
pub maximum: Option<f32>,
));
gen.extend(quote!(
#[serde(skip_serializing_if = "Option::is_none")]
pub minimum: Option<f32>,
));
gen.extend(quote!(
#[serde(skip_serializing_if = "Option::is_none")]
pub example: Option<serde_json::Value>,
Expand Down
25 changes: 20 additions & 5 deletions tests/test_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1944,7 +1944,9 @@ fn test_serde_flatten() {
},
"age": {
"format": "int32",
"type": "integer"
"type": "integer",
"maximum": 255.0,
"minimum": 0.0,
},
"description": {
"type": "string"
Expand All @@ -1971,7 +1973,9 @@ fn test_serde_flatten() {
},
"age": {
"format": "int32",
"type": "integer"
"type": "integer",
"maximum": 255.0,
"minimum": 0.0,
},
"data": {
"type": "string"
Expand Down Expand Up @@ -2151,7 +2155,12 @@ fn test_serde_skip() {
}

#[derive(Deserialize, Serialize, Apiv2Schema)]
struct PetUnnamed(#[serde(skip)] bool, bool);
struct PetUnnamed(
#[serde(skip)]
#[allow(dead_code)]
bool,
bool,
);

#[post("/v0/pets")]
#[api_v2_operation]
Expand Down Expand Up @@ -3996,7 +4005,11 @@ fn test_header_parameter_app() {
}

#[derive(Apiv2Header, Deserialize)]
struct RefererHeader(#[openapi(name = "X-Referer-slug")] String);
struct RefererHeader(
#[openapi(name = "X-Referer-slug")]
#[allow(dead_code)]
String,
);

impl FromRequest for RefererHeader {
type Error = Error;
Expand Down Expand Up @@ -4851,7 +4864,9 @@ fn test_example() {
"age": {
"description": "7 time yours",
"format": "int32",
"type": "integer"
"type": "integer",
"maximum": 255.0,
"minimum": 0.0,
},
"name": {
"description": "Pick a good one.",
Expand Down

0 comments on commit 135096f

Please sign in to comment.