Skip to content

Commit 4f69686

Browse files
committed
feat: add support for cdevents 0.4
- with some hack, shortcut to improve
1 parent b778dd5 commit 4f69686

File tree

8 files changed

+70
-9
lines changed

8 files changed

+70
-9
lines changed

.gitmodules

+4
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@
55
[submodule "cdevents-specs/main"]
66
path = cdevents-specs/main
77
url = https://github.com/cdevents/spec.git
8+
[submodule "cdevents-specs/spec-v0.4"]
9+
path = cdevents-specs/spec-v0.4
10+
url = https://github.com/cdevents/spec.git
11+
branch = spec-v0.4

Makefile

+8
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@ test:
7575
cargo nextest run --all-features
7676
cargo test --doc
7777

78+
# buid_cdevents-specs:
79+
# git submodule deinit -f --all
80+
# git submodule init
81+
# git submodule add -f https://github.com/cdevents/spec.git cdevents-specs/main
82+
# git submodule add -f -b spec-v0.3 https://github.com/cdevents/spec.git cdevents-specs/spec-v0.3
83+
# git submodule add -f -b spec-v0.4 https://github.com/cdevents/spec.git cdevents-specs/spec-v0.4
84+
# git submodule update -f --rebase -- cdevents-specs/main
85+
7886
.PHONY:
7987
generate \
8088
check check_no_uncommitted_changes_on_sdk \

cdevents-sdk/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ assert-json-diff = "2.0"
2424
boon = "0.5"
2525
glob = "0.3"
2626
proptest = "1"
27-
rstest = "0.18"
27+
rstest = "0.19"
2828

2929
[features]
3030
default = ["cloudevents"]

cdevents-sdk/src/context.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use serde::{Deserialize, Serialize};
22

3-
use crate::{Id, UriReference};
3+
use crate::{Id, Uri, UriReference};
44

55
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
66
#[serde(deny_unknown_fields)]
@@ -12,6 +12,12 @@ pub(crate) struct Context {
1212
pub(crate) ty: String,
1313
#[serde(with = "crate::serde::datetime")]
1414
pub(crate) timestamp: time::OffsetDateTime,
15+
#[serde(rename = "schemaUri", skip_serializing_if = "Option::is_none")]
16+
pub(crate) schema_uri: Option<Uri>,
17+
#[serde(rename = "chain_id", skip_serializing_if = "Option::is_none")]
18+
pub(crate) chain_id: Option<String>,
19+
#[serde(skip_serializing_if = "Option::is_none")]
20+
pub(crate) links: Option<serde_json::Value>,
1521
}
1622

1723
impl Default for Context {
@@ -22,6 +28,9 @@ impl Default for Context {
2228
source: "/undef".try_into().expect("/undef is a valid uri-reference"),
2329
ty: "dev.cdevents.undef.undef.0.0.0".into(),
2430
timestamp: time::OffsetDateTime::now_utc(),
31+
schema_uri: None,
32+
chain_id: None,
33+
links: None,
2534
}
2635
}
2736
}

cdevents-sdk/tests/specs.rs

+20-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rstest::*;
44
use std::{collections::HashMap, fs};
55
use std::path::PathBuf;
66
use proptest::prelude::*;
7-
use boon::{Schemas, Compiler, SchemaIndex};
7+
use boon::{Compiler, SchemaIndex, Schemas, UrlLoader};
88
use glob::glob;
99
use std::sync::OnceLock;
1010

@@ -18,6 +18,10 @@ impl EventsSchemas {
1818
let mut schemas = Schemas::new();
1919
let mut compiler = Compiler::new();
2020
let mut mapping = HashMap::new();
21+
22+
//HACK to resolve invalid `$ref: "/schema/links/embeddedlinksarray.json"`
23+
compiler.register_url_loader("https", Box::new(HackUrlLoader{}));
24+
2125
for entry in glob("../cdevents-specs/*/schemas/*.json").expect("Failed to read glob pattern") {
2226
let schemapath = entry.unwrap();
2327
//TODO avoid to read the schema twice (as json, then as jsonschema)
@@ -47,14 +51,27 @@ impl EventsSchemas {
4751
}
4852
}
4953

54+
struct HackUrlLoader;
55+
56+
impl UrlLoader for HackUrlLoader {
57+
fn load(&self, url: &str) -> Result<serde_json::Value, Box<dyn std::error::Error>> {
58+
if url.starts_with("https://cdevents.dev/schema/links/") {
59+
let path = url.replace("https://cdevents.dev/schema", "../cdevents-specs/spec-v0.4/schemas/");
60+
let jsonschema: serde_json::Value = serde_json::from_str(&std::fs::read_to_string(path)?)?;
61+
Ok(jsonschema)
62+
} else {
63+
Err(format!("fail to load {url}").into())
64+
}
65+
}
66+
}
5067
static EVENTS_SCHEMA_CELL: OnceLock<EventsSchemas> = OnceLock::new();
5168

5269
fn events_schemas() -> &'static EventsSchemas {
5370
EVENTS_SCHEMA_CELL.get_or_init(EventsSchemas::load)
5471
}
5572

5673
#[rstest]
57-
fn for_each_example(#[files("../cdevents-specs/spec-v0.3/examples/*.json")] path: PathBuf) {
74+
fn can_serde_example(#[files("../cdevents-specs/spec-*/examples/*.json")] path: PathBuf) {
5875
let example_txt = fs::read_to_string(path).expect("to read file as string");
5976
//HACK uri are stored ad http::Uri, they are "normalized" when serialized, so prenormalization to avoid failure like
6077
// json atoms at path ".subject.content.repository.source" are not equal:
@@ -78,7 +95,7 @@ fn for_each_example(#[files("../cdevents-specs/spec-v0.3/examples/*.json")] path
7895
}
7996

8097
#[rstest]
81-
fn validate_example_against_schema(#[files("../cdevents-specs/spec-v0.3/examples/*.json")] path: PathBuf) {
98+
fn validate_example_against_schema(#[files("../cdevents-specs/spec-*/examples/*.json")] path: PathBuf) {
8299
let events_schemas = events_schemas();
83100
let example_txt = fs::read_to_string(path).expect("to read file as string");
84101
let example_json: serde_json::Value =

cdevents-specs/spec-v0.4

Submodule spec-v0.4 added at b462f84

generator/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ Goals: generate rust code for cdevents from jsonschema provided as part of cdeve
1313

1414
## Run
1515

16-
To generate the `subjects` into sibling crate `cdevents/src/generated` from content of `cdevents-specs/spec-v0.3/schemas`, from root workspace
16+
To generate the `subjects` into sibling crate `cdevents/src/generated` from content of `cdevents-specs/spec-v0.4/schemas`, from root workspace
1717

1818
```sh
1919
cargo run -p generator -- --help
20-
cargo run -p generator -- --templates-dir "generator/templates" --jsonschema-dir "cdevents-specs/spec-v0.3/schemas" --dest "cdevents-sdk/src/generated"
20+
cargo run -p generator -- --templates-dir "generator/templates" --jsonschema-dir "cdevents-specs/spec-v0.4/schemas" --dest "cdevents-sdk/src/generated"
2121
```

generator/src/main.rs

+24-2
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,30 @@ fn collect_structs(
328328
type_info
329329
}
330330
},
331-
Some(x) => todo!("impl for type='{}'", x),
332-
None => unimplemented!("expected key 'type' in field '{}'", field_names.join(".")),
331+
// Some("array") => TypeInfo {
332+
// type_declaration: "serde_json::Array<serde_json::Value>".to_string(),
333+
// ..Default::default()
334+
// },
335+
Some(x) => match field_names.last() {
336+
// HACK for array of string
337+
Some(&"assignees") | Some(&"labels") => TypeInfo {
338+
type_declaration: "Vec<String>".to_string(),
339+
..Default::default()
340+
},
341+
_ => todo!(
342+
"impl for type='{}' for field='{}'",
343+
x,
344+
field_names.join(".")
345+
),
346+
},
347+
None => match field_names.last() {
348+
// HACK for an anyOf (string or enum/string)
349+
Some(&"priority") | Some(&"ticketType") | Some(&"resolution") => TypeInfo {
350+
type_declaration: "String".to_string(),
351+
..Default::default()
352+
},
353+
_ => unimplemented!("expected key 'type' in field '{}'", field_names.join(".")),
354+
},
333355
}
334356
}
335357

0 commit comments

Comments
 (0)