Skip to content

Commit

Permalink
aw-models: Add custom schema for tryparse
Browse files Browse the repository at this point in the history
  • Loading branch information
johan-bjareholt committed Oct 29, 2020
1 parent 96cbc9d commit 03fd9cd
Showing 1 changed file with 23 additions and 15 deletions.
38 changes: 23 additions & 15 deletions aw-models/src/tryvec.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use schemars::JsonSchema;
use schemars::{gen::SchemaGenerator, schema::Schema, JsonSchema};
use serde::de::{DeserializeOwned, SeqAccess, Visitor};
use serde::export::PhantomData;
use serde::ser::SerializeSeq;
Expand All @@ -7,17 +7,24 @@ use serde_json::Value;
use std::fmt;
use std::fmt::Debug;

#[derive(Debug, Clone, JsonSchema)]
#[serde(untagged)]
// TODO: JsonSchema is invalid, we should only allow "Parsed" value as the
// others will be dropped
pub enum TryParse<T> {
#[derive(Debug, Clone)]
pub enum TryParse<T: JsonSchema> {
Parsed(T),
Unparsed(Value),
NotPresent,
}

impl<'de, T: DeserializeOwned> Deserialize<'de> for TryParse<T> {
impl<T: JsonSchema> JsonSchema for TryParse<T> {
fn schema_name() -> String {
format!("Try<{}>", std::any::type_name::<T>())
}

fn json_schema(gen: &mut SchemaGenerator) -> Schema {
gen.subschema_for::<T>()
}
}

impl<'de, T: DeserializeOwned + JsonSchema> Deserialize<'de> for TryParse<T> {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
match Option::<Value>::deserialize(deserializer)? {
None => Ok(TryParse::NotPresent),
Expand All @@ -31,11 +38,11 @@ impl<'de, T: DeserializeOwned> Deserialize<'de> for TryParse<T> {

#[derive(Debug, Clone, JsonSchema)]
#[serde(transparent)]
pub struct TryVec<T> {
pub struct TryVec<T: JsonSchema> {
inner: Vec<TryParse<T>>,
}

impl<T> TryVec<T> {
impl<T: JsonSchema> TryVec<T> {
pub fn new(mut vec: Vec<T>) -> Self {
let mut vec_marked: Vec<TryParse<T>> = Vec::new();
for item in vec.drain(..) {
Expand All @@ -60,7 +67,7 @@ impl<T> TryVec<T> {
}
}

impl<T> Serialize for TryVec<T>
impl<T: JsonSchema> Serialize for TryVec<T>
where
T: Serialize,
{
Expand All @@ -79,11 +86,11 @@ where
}
}

struct TryVecVisitor<T> {
struct TryVecVisitor<T: JsonSchema> {
marker: PhantomData<fn() -> TryVec<T>>,
}

impl<T> TryVecVisitor<T> {
impl<T: JsonSchema> TryVecVisitor<T> {
fn new() -> Self {
TryVecVisitor {
marker: PhantomData,
Expand All @@ -93,7 +100,7 @@ impl<T> TryVecVisitor<T> {

impl<'de, T> Visitor<'de> for TryVecVisitor<T>
where
T: DeserializeOwned,
T: DeserializeOwned + JsonSchema,
{
type Value = TryVec<T>;

Expand Down Expand Up @@ -129,7 +136,7 @@ where
}
}

impl<'de, T> Deserialize<'de> for TryVec<T>
impl<'de, T: JsonSchema> Deserialize<'de> for TryVec<T>
where
T: DeserializeOwned,
{
Expand All @@ -143,11 +150,12 @@ where

#[cfg(test)]
mod test {
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use super::TryVec;

#[derive(Deserialize, Serialize, Debug)]
#[derive(Deserialize, Serialize, JsonSchema, Debug)]
struct TestEvent {
data: String,
}
Expand Down

0 comments on commit 03fd9cd

Please sign in to comment.