fix property sorting

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2020-01-23 13:15:59 +01:00
parent d07286c7a3
commit edebbf920a
3 changed files with 39 additions and 28 deletions

View File

@ -336,19 +336,28 @@ impl SchemaItem {
#[derive(Default)]
/// Contains a sorted list of properties:
pub struct SchemaObject {
properties: Vec<(FieldName, bool, Schema)>,
properties_: Vec<(FieldName, bool, Schema)>,
}
impl SchemaObject {
pub fn new() -> Self {
Self {
properties: Vec::new(),
properties_: Vec::new(),
}
}
#[inline]
fn properties_mut(&mut self) -> &mut [(FieldName, bool, Schema)] {
&mut self.properties_
}
fn sort_properties(&mut self) {
self.properties_.sort_by(|a, b| (a.0).cmp(&b.0));
}
fn try_extract_from(obj: &mut JSONObject) -> Result<Self, syn::Error> {
Ok(Self {
properties: obj
let mut this = Self {
properties_: obj
.remove_required_element("properties")?
.into_object("object field definition")?
.into_iter()
@ -371,17 +380,14 @@ impl SchemaObject {
Ok(properties)
},
)
// This must be kept sorted!
.map(|mut properties| {
properties.sort_by(|a, b| (a.0).cmp(&b.0));
properties
})?,
})
)?,
};
this.sort_properties();
Ok(this)
}
fn to_schema_inner(&self, ts: &mut TokenStream) -> Result<(), Error> {
for element in self.properties.iter() {
for element in self.properties_.iter() {
let key = element.0.as_str();
let optional = element.1;
let mut schema = TokenStream::new();
@ -393,23 +399,28 @@ impl SchemaObject {
fn find_property_by_ident(&self, key: &str) -> Option<&(FieldName, bool, Schema)> {
match self
.properties
.properties_
.binary_search_by(|p| p.0.as_ident_str().cmp(key))
{
Ok(idx) => Some(&self.properties[idx]),
Ok(idx) => Some(&self.properties_[idx]),
Err(_) => None,
}
}
fn find_property_by_ident_mut(&mut self, key: &str) -> Option<&mut (FieldName, bool, Schema)> {
match self
.properties
.properties_
.binary_search_by(|p| p.0.as_ident_str().cmp(key))
{
Ok(idx) => Some(&mut self.properties[idx]),
Ok(idx) => Some(&mut self.properties_[idx]),
Err(_) => None,
}
}
fn extend_properties(&mut self, new_fields: Vec<(FieldName, bool, Schema)>) {
self.properties_.extend(new_fields);
self.sort_properties();
}
}
pub struct SchemaArray {

View File

@ -73,7 +73,7 @@ fn handle_regular_struct(
// We also keep a reference to the SchemaObject around since we derive missing fields
// automatically.
if let api::SchemaItem::Object(ref mut obj) = &mut schema.item {
for field in &mut obj.properties {
for field in obj.properties_mut() {
schema_fields.insert(field.0.as_str().to_string(), field);
}
} else {
@ -140,7 +140,7 @@ fn handle_regular_struct(
// add the fields we derived:
if let api::SchemaItem::Object(ref mut obj) = &mut schema.item {
obj.properties.extend(new_fields);
obj.extend_properties(new_fields);
} else {
unreachable!();
}

View File

@ -43,11 +43,6 @@ fn test_struct() {
&::proxmox::api::schema::ObjectSchema::new(
"An example of a simple struct type.",
&[
(
"test_string",
false,
&::proxmox::api::schema::StringSchema::new("A test string.").schema(),
),
(
"another",
true,
@ -56,6 +51,11 @@ fn test_struct() {
)
.schema(),
),
(
"test_string",
false,
&::proxmox::api::schema::StringSchema::new("A test string.").schema(),
),
],
)
.schema();
@ -82,11 +82,6 @@ fn renamed_struct() {
&::proxmox::api::schema::ObjectSchema::new(
"An example of a struct with renamed fields.",
&[
(
"test-string",
false,
&::proxmox::api::schema::StringSchema::new("A test string.").schema(),
),
(
"SomeOther",
true,
@ -95,6 +90,11 @@ fn renamed_struct() {
)
.schema(),
),
(
"test-string",
false,
&::proxmox::api::schema::StringSchema::new("A test string.").schema(),
),
],
)
.schema();