Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ diff = []

[dependencies]
jsonptr = "0.7.1"
schemars = { version = "0.8", optional = true }
serde = { version = "1.0.159", features = ["derive"] }
serde_json = "1.0.95"
thiserror = "1.0.40"
Expand All @@ -24,6 +25,7 @@ utoipa = { version = "4.0", optional = true }
[dev-dependencies]
expectorate = "1.0"
rand = "0.8.5"
schemars = "0.8.22"
serde_json = { version = "1.0.95", features = ["preserve_order"] }
serde_yaml = "0.9.19"
utoipa = { version = "4.0", features = ["debug"] }
16 changes: 16 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ macro_rules! impl_display {

/// Representation of JSON Patch (list of patch operations)
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct Patch(pub Vec<PatchOperation>);

Expand All @@ -144,10 +145,12 @@ impl std::ops::Deref for Patch {

/// JSON Patch 'add' operation representation
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct AddOperation {
/// JSON-Pointer value [RFC6901](https://tools.ietf.org/html/rfc6901) that references a location
/// within the target document where the operation is performed.
#[cfg_attr(feature = "schemars", schemars(schema_with = "String::json_schema"))]
#[cfg_attr(feature = "utoipa", schema(value_type = String))]
pub path: PointerBuf,
/// Value to add to the target location.
Expand All @@ -158,10 +161,12 @@ impl_display!(AddOperation);

/// JSON Patch 'remove' operation representation
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct RemoveOperation {
/// JSON-Pointer value [RFC6901](https://tools.ietf.org/html/rfc6901) that references a location
/// within the target document where the operation is performed.
#[cfg_attr(feature = "schemars", schemars(schema_with = "String::json_schema"))]
#[cfg_attr(feature = "utoipa", schema(value_type = String))]
pub path: PointerBuf,
}
Expand All @@ -170,10 +175,12 @@ impl_display!(RemoveOperation);

/// JSON Patch 'replace' operation representation
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct ReplaceOperation {
/// JSON-Pointer value [RFC6901](https://tools.ietf.org/html/rfc6901) that references a location
/// within the target document where the operation is performed.
#[cfg_attr(feature = "schemars", schemars(schema_with = "String::json_schema"))]
#[cfg_attr(feature = "utoipa", schema(value_type = String))]
pub path: PointerBuf,
/// Value to replace with.
Expand All @@ -184,14 +191,17 @@ impl_display!(ReplaceOperation);

/// JSON Patch 'move' operation representation
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct MoveOperation {
/// JSON-Pointer value [RFC6901](https://tools.ietf.org/html/rfc6901) that references a location
/// to move value from.
#[cfg_attr(feature = "schemars", schemars(schema_with = "String::json_schema"))]
#[cfg_attr(feature = "utoipa", schema(value_type = String))]
pub from: PointerBuf,
/// JSON-Pointer value [RFC6901](https://tools.ietf.org/html/rfc6901) that references a location
/// within the target document where the operation is performed.
#[cfg_attr(feature = "schemars", schemars(schema_with = "String::json_schema"))]
#[cfg_attr(feature = "utoipa", schema(value_type = String))]
pub path: PointerBuf,
}
Expand All @@ -200,14 +210,17 @@ impl_display!(MoveOperation);

/// JSON Patch 'copy' operation representation
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct CopyOperation {
/// JSON-Pointer value [RFC6901](https://tools.ietf.org/html/rfc6901) that references a location
/// to copy value from.
#[cfg_attr(feature = "schemars", schemars(schema_with = "String::json_schema"))]
#[cfg_attr(feature = "utoipa", schema(value_type = String))]
pub from: PointerBuf,
/// JSON-Pointer value [RFC6901](https://tools.ietf.org/html/rfc6901) that references a location
/// within the target document where the operation is performed.
#[cfg_attr(feature = "schemars", schemars(schema_with = "String::json_schema"))]
#[cfg_attr(feature = "utoipa", schema(value_type = String))]
pub path: PointerBuf,
}
Expand All @@ -216,10 +229,12 @@ impl_display!(CopyOperation);

/// JSON Patch 'test' operation representation
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct TestOperation {
/// JSON-Pointer value [RFC6901](https://tools.ietf.org/html/rfc6901) that references a location
/// within the target document where the operation is performed.
#[cfg_attr(feature = "schemars", schemars(schema_with = "String::json_schema"))]
#[cfg_attr(feature = "utoipa", schema(value_type = String))]
pub path: PointerBuf,
/// Value to test against.
Expand All @@ -230,6 +245,7 @@ impl_display!(TestOperation);

/// JSON Patch single patch operation
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(tag = "op")]
#[serde(rename_all = "lowercase")]
Expand Down
149 changes: 149 additions & 0 deletions tests/schemars.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PatchOperation",
"description": "JSON Patch single patch operation",
"oneOf": [
{
"description": "'add' operation",
"type": "object",
"required": [
"op",
"path",
"value"
],
"properties": {
"op": {
"type": "string",
"enum": [
"add"
]
},
"path": {
"description": "JSON-Pointer value [RFC6901](https://tools.ietf.org/html/rfc6901) that references a location within the target document where the operation is performed.",
"type": "string"
},
"value": {
"description": "Value to add to the target location."
}
}
},
{
"description": "'remove' operation",
"type": "object",
"required": [
"op",
"path"
],
"properties": {
"op": {
"type": "string",
"enum": [
"remove"
]
},
"path": {
"description": "JSON-Pointer value [RFC6901](https://tools.ietf.org/html/rfc6901) that references a location within the target document where the operation is performed.",
"type": "string"
}
}
},
{
"description": "'replace' operation",
"type": "object",
"required": [
"op",
"path",
"value"
],
"properties": {
"op": {
"type": "string",
"enum": [
"replace"
]
},
"path": {
"description": "JSON-Pointer value [RFC6901](https://tools.ietf.org/html/rfc6901) that references a location within the target document where the operation is performed.",
"type": "string"
},
"value": {
"description": "Value to replace with."
}
}
},
{
"description": "'move' operation",
"type": "object",
"required": [
"from",
"op",
"path"
],
"properties": {
"from": {
"description": "JSON-Pointer value [RFC6901](https://tools.ietf.org/html/rfc6901) that references a location to move value from.",
"type": "string"
},
"op": {
"type": "string",
"enum": [
"move"
]
},
"path": {
"description": "JSON-Pointer value [RFC6901](https://tools.ietf.org/html/rfc6901) that references a location within the target document where the operation is performed.",
"type": "string"
}
}
},
{
"description": "'copy' operation",
"type": "object",
"required": [
"from",
"op",
"path"
],
"properties": {
"from": {
"description": "JSON-Pointer value [RFC6901](https://tools.ietf.org/html/rfc6901) that references a location to copy value from.",
"type": "string"
},
"op": {
"type": "string",
"enum": [
"copy"
]
},
"path": {
"description": "JSON-Pointer value [RFC6901](https://tools.ietf.org/html/rfc6901) that references a location within the target document where the operation is performed.",
"type": "string"
}
}
},
{
"description": "'test' operation",
"type": "object",
"required": [
"op",
"path",
"value"
],
"properties": {
"op": {
"type": "string",
"enum": [
"test"
]
},
"path": {
"description": "JSON-Pointer value [RFC6901](https://tools.ietf.org/html/rfc6901) that references a location within the target document where the operation is performed.",
"type": "string"
},
"value": {
"description": "Value to test against."
}
}
}
]
}
9 changes: 9 additions & 0 deletions tests/schemars.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#[cfg(feature = "schemars")]
#[test]
fn schema() {
use json_patch::*;

let schema = schemars::schema_for!(PatchOperation);
let json = serde_json::to_string_pretty(&schema).unwrap();
expectorate::assert_contents("tests/schemars.json", &json);
}
Loading