Skip to content

Commit fdf192b

Browse files
committed
feat: accept to deserialize & serialize custom event (content is defined as JSON)
Signed-off-by: David Bernard <[email protected]>
1 parent e9c9fbb commit fdf192b

File tree

3 files changed

+53
-25
lines changed

3 files changed

+53
-25
lines changed

cdevents-sdk/src/generated/mod.rs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,12 @@ pub enum Content {
438438
TicketClosed010(ticket_closed_0_1_0::Content),
439439
TicketCreated010(ticket_created_0_1_0::Content),
440440
TicketUpdated010(ticket_updated_0_1_0::Content),
441+
Custom{
442+
#[serde(skip)]
443+
ty: String,
444+
#[serde(flatten)]
445+
json: serde_json::Value,
446+
},
441447
}
442448

443449
impl Content {
@@ -783,14 +789,18 @@ impl Content {
783789
let variant: ticket_updated_0_1_0::Content = serde_json::from_value(json)?;
784790
Ok(variant.into())
785791
},
786-
variant => Err(serde_json::Error::custom(format_args!(
787-
"unknown variant `{}`, expected 'dev.cdevents.{{subject}}.{{predicate}}.{{version}}'",
788-
variant,
789-
))),
792+
variant => if variant.starts_with("dev.cdeventsx.") {
793+
Ok(Self::Custom{ ty: ty.to_string(), json })
794+
} else {
795+
Err(serde_json::Error::custom(format_args!(
796+
"unknown variant `{}`, expected 'dev.cdevents.{{subject}}.{{predicate}}.{{version}}'",
797+
variant,
798+
)))
799+
},
790800
}
791801
}
792802

793-
pub fn ty(&self) -> &'static str {
803+
pub fn ty(&self) -> &str {
794804
match self {
795805
Self::ArtifactDeleted010(_) => ARTIFACT_DELETED_0_1_0,
796806
Self::ArtifactDownloaded010(_) => ARTIFACT_DOWNLOADED_0_1_0,
@@ -877,10 +887,11 @@ impl Content {
877887
Self::TicketClosed010(_) => TICKET_CLOSED_0_1_0,
878888
Self::TicketCreated010(_) => TICKET_CREATED_0_1_0,
879889
Self::TicketUpdated010(_) => TICKET_UPDATED_0_1_0,
890+
Self::Custom{ty, ..} => ty,
880891
}
881892
}
882893

883-
pub fn subject(&self) -> &'static str {
894+
pub fn subject(&self) -> &str {
884895
match self {
885896
Self::ArtifactDeleted010(_) => "artifact",
886897
Self::ArtifactDownloaded010(_) => "artifact",
@@ -967,10 +978,11 @@ impl Content {
967978
Self::TicketClosed010(_) => "ticket",
968979
Self::TicketCreated010(_) => "ticket",
969980
Self::TicketUpdated010(_) => "ticket",
981+
Self::Custom{ty, ..} => ty.split('.').nth(2).unwrap_or_default(),
970982
}
971983
}
972984

973-
pub fn predicate(&self) -> &'static str {
985+
pub fn predicate(&self) -> &str {
974986
match self {
975987
Self::ArtifactDeleted010(_) => "deleted",
976988
Self::ArtifactDownloaded010(_) => "downloaded",
@@ -1057,11 +1069,13 @@ impl Content {
10571069
Self::TicketClosed010(_) => "closed",
10581070
Self::TicketCreated010(_) => "created",
10591071
Self::TicketUpdated010(_) => "updated",
1072+
Self::Custom{ty, ..} => ty.split('.').nth(3).unwrap_or_default(),
10601073
}
10611074
}
10621075
}
10631076

1064-
// due to inconstency in case/format the subject could be not be extracted from the context.type (ty), jsonshema $id, spec filename (shema, examples)
1077+
/// Due to inconstency in case/format the subject could be not be extracted from the context.type (ty), jsonshema $id, spec filename (shema, examples)
1078+
/// Custom type are not supported
10651079
pub fn extract_subject_predicate(ty: &str) -> Option<(&str, &str)>{
10661080
// let mut split = ty.split('.');
10671081
match ty {
@@ -1680,7 +1694,7 @@ impl<> proptest::arbitrary::Arbitrary for Content {
16801694
// #[cfg(test)]
16811695
// mod tests {
16821696
// use super::*;
1683-
//
1697+
//
16841698
// #[test]
16851699
// fn test_true() {
16861700
//
@@ -1855,4 +1869,4 @@ impl<> proptest::arbitrary::Arbitrary for Content {
18551869
// assert_eq!(extract_subject_predicate(TICKET_UPDATED_0_1_0), Some(("ticket","updated")));
18561870
//
18571871
// }
1858-
// }
1872+
// }

cdevents-sdk/tests/specs.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,12 @@ impl UrlLoader for HackUrlLoader {
7777
}
7878
static EVENTS_SCHEMA_CELL: OnceLock<EventsSchemas> = OnceLock::new();
7979

80-
fn events_schemas() -> &'static EventsSchemas {
80+
fn events_schemas() -> &'static EventsSchemas {
8181
EVENTS_SCHEMA_CELL.get_or_init(EventsSchemas::load)
8282
}
8383

8484
#[rstest]
85-
fn can_serde_example(#[files("../cdevents-specs/spec-*/examples/*.json")] #[files("../cdevents-specs/spec-*/conformance/*.json")] path: PathBuf) {
85+
fn can_serde_example(#[files("../cdevents-specs/spec-*/examples/*.json")] #[files("../cdevents-specs/spec-*/conformance/*.json")] #[files("../cdevents-specs/spec-*/custom/conformance.json")] path: PathBuf) {
8686
let example_txt = fs::read_to_string(path).expect("to read file as string");
8787
// HACK uri are stored ad http::Uri, they are "normalized" when serialized, so prenormalization to avoid failure like
8888
// json atoms at path ".subject.content.repository.source" are not equal:
@@ -96,12 +96,12 @@ fn can_serde_example(#[files("../cdevents-specs/spec-*/examples/*.json")] #[file
9696

9797
let example_json: serde_json::Value =
9898
serde_json::from_str(&example_txt).expect("to parse as json");
99-
dbg!(&example_json);
99+
// dbg!(&example_json);
100100
let cdevent: CDEvent =
101101
serde_json::from_value(example_json.clone()).expect("to parse as cdevent");
102-
dbg!(&cdevent);
102+
// dbg!(&cdevent);
103103
let cdevent_json = serde_json::to_value(cdevent).expect("to convert into json");
104-
dbg!(&cdevent_json);
104+
// dbg!(&cdevent_json);
105105
assert_json_eq!(example_json, cdevent_json);
106106
}
107107

generator/templates/mod.hbs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ pub enum Content {
2525
{{#each variants }}
2626
{{to_class_case this.rust_module}}({{this.rust_module}}::Content),
2727
{{/each}}
28+
Custom{
29+
#[serde(skip)]
30+
ty: String,
31+
#[serde(flatten)]
32+
json: serde_json::Value,
33+
},
2834
}
2935

3036
impl Content {
@@ -36,39 +42,47 @@ impl Content {
3642
Ok(variant.into())
3743
},
3844
{{/each}}
39-
variant => Err(serde_json::Error::custom(format_args!(
40-
"unknown variant `{}`, expected 'dev.cdevents.\{{subject}}.\{{predicate}}.\{{version}}'",
41-
variant,
42-
))),
45+
variant => if variant.starts_with("dev.cdeventsx.") {
46+
Ok(Self::Custom{ ty: ty.to_string(), json })
47+
} else {
48+
Err(serde_json::Error::custom(format_args!(
49+
"unknown variant `{}`, expected 'dev.cdevents.\{{subject}}.\{{predicate}}.\{{version}}'",
50+
variant,
51+
)))
52+
},
4353
}
4454
}
4555

46-
pub fn ty(&self) -> &'static str {
56+
pub fn ty(&self) -> &str {
4757
match self {
4858
{{#each variants }}
4959
Self::{{to_class_case this.rust_module}}(_) => {{to_screaming_snake_case this.rust_module}},
5060
{{/each}}
61+
Self::Custom{ty, ..} => ty,
5162
}
5263
}
5364

54-
pub fn subject(&self) -> &'static str {
65+
pub fn subject(&self) -> &str {
5566
match self {
5667
{{#each variants }}
5768
Self::{{to_class_case this.rust_module}}(_) => "{{ this.subject_type }}",
5869
{{/each}}
70+
Self::Custom{ty, ..} => ty.split('.').nth(2).unwrap_or_default(),
5971
}
6072
}
6173

62-
pub fn predicate(&self) -> &'static str {
74+
pub fn predicate(&self) -> &str {
6375
match self {
6476
{{#each variants }}
6577
Self::{{to_class_case this.rust_module}}(_) => "{{ this.predicate }}",
6678
{{/each}}
79+
Self::Custom{ty, ..} => ty.split('.').nth(3).unwrap_or_default(),
6780
}
6881
}
6982
}
7083

71-
// due to inconstency in case/format the subject could be not be extracted from the context.type (ty), jsonshema $id, spec filename (shema, examples)
84+
/// Due to inconstency in case/format the subject could be not be extracted from the context.type (ty), jsonshema $id, spec filename (shema, examples)
85+
/// Custom type are not supported
7286
pub fn extract_subject_predicate(ty: &str) -> Option<(&str, &str)>{
7387
// let mut split = ty.split('.');
7488
match ty {
@@ -105,11 +119,11 @@ impl<> proptest::arbitrary::Arbitrary for Content {
105119
// #[cfg(test)]
106120
// mod tests {
107121
// use super::*;
108-
//
122+
//
109123
// #[test]
110124
// fn test_true() {
111125
// {{#each variants }}
112126
// assert_eq!(extract_subject_predicate({{to_screaming_snake_case this.rust_module}}), Some(("{{ this.subject }}","{{ this.predicate }}")));
113127
// {{/each}}
114128
// }
115-
// }
129+
// }

0 commit comments

Comments
 (0)