Skip to content

Commit

Permalink
Fix #14: allOf correctly marks non-required fields as optional
Browse files Browse the repository at this point in the history
  • Loading branch information
kurtbuilds committed Oct 8, 2023
1 parent c920729 commit 66e3ef6
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 6 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[workspace]
resolver = "2"
members = [
"libninja",
"macro",
Expand Down
1 change: 1 addition & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ generate:
cargo run -- gen --name $SERVICE --output-dir $REPO_DIR --generator $SOURCEGEN --github $REPO --version $VERSION $LIBRARY $SPEC

test *ARGS:
cd core && cargo test -- "$@"
cd libninja && cargo test -- "$@"
alias t := test

Expand Down
3 changes: 3 additions & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@ syn = "2.0"
ln-mir = { path = "../mir" }
include_dir = "0.7.3"
tera = "1.19.0"

[dev-dependencies]
serde_yaml = "0.9.25"
13 changes: 13 additions & 0 deletions core/src/extractor/pet_tag.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
allOf:
- type: object
required:
- eye-color
properties:
eye-color:
type: string
enum:
- blue
- brown
- green
weight:
type: integer
24 changes: 23 additions & 1 deletion core/src/extractor/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,10 @@ fn create_record_from_all_of(name: &str, all_of: &[ReferenceOr<Schema>], schema_
match item.properties() {
Some(props) => {
for (name, schema) in props {
let field = create_field(schema, spec);
let mut field = create_field(schema, spec);
if !item.required(name) {
field.optional = true;
}
fields.insert(Name::new(name), field);
}
}
Expand Down Expand Up @@ -154,3 +157,22 @@ pub fn extract_records(spec: &OpenAPI) -> Result<BTreeMap<String, Record>> {
.collect::<Result<_>>()?;
Ok(result)
}

#[cfg(test)]
mod tests {
use openapiv3::{OpenAPI, ReferenceOr, Schema, SchemaData, SchemaKind};
use crate::extractor::record::create_record_from_all_of;

#[test]
fn test_all_of_required_set_correctly() {
let mut additional_props: Schema = serde_yaml::from_str(include_str!("./pet_tag.yaml")).unwrap();
let SchemaKind::AllOf { all_of } = &additional_props.schema_kind else { panic!() };
let spec = OpenAPI::default();
let rec = create_record_from_all_of("PetTag", &all_of, &SchemaData::default(), &spec);
let mut fields = rec.fields();
let eye_color = fields.next().unwrap();
let weight = fields.next().unwrap();
assert_eq!(eye_color.optional, false);
assert_eq!(weight.optional, true);
}
}
1 change: 1 addition & 0 deletions core/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ pub struct StrEnum {
pub variants: Vec<String>,
}

// an object type in the HIR
#[derive(Debug, Clone)]
pub enum Record {
Struct(Struct),
Expand Down
1 change: 1 addition & 0 deletions libninja/tests/all_of/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ fn test_transaction() {

let record = record_for_schema("Transaction", TRANSACTION, &spec);
let code = formatted_code(record);
println!("{}", code);
assert_eq!(code, TRANSACTION_RS);
}

Expand Down
9 changes: 6 additions & 3 deletions libninja/tests/all_of/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ pub struct Transaction {
pub authorized_date: Option<chrono::NaiveDate>,
#[serde(skip_serializing_if = "Option::is_none")]
pub authorized_datetime: Option<chrono::DateTime<chrono::Utc>>,
pub counterparties: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub counterparties: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub datetime: Option<chrono::DateTime<chrono::Utc>>,
pub payment_channel: String,
pub personal_finance_category: String,
pub personal_finance_category_icon_url: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub personal_finance_category: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub personal_finance_category_icon_url: Option<String>,
pub transaction_code: String,
}
impl std::fmt::Display for Transaction {
Expand Down

0 comments on commit 66e3ef6

Please sign in to comment.