Skip to content

Commit

Permalink
transform for removing attribute ns prefix
Browse files Browse the repository at this point in the history
  • Loading branch information
ciscorn committed Jan 25, 2024
1 parent 2a393cf commit d9b6368
Show file tree
Hide file tree
Showing 66 changed files with 24,900 additions and 169 deletions.
6 changes: 3 additions & 3 deletions app/src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use nusamai::sink::{
geojson::GeoJsonSinkProvider, gpkg::GpkgSinkProvider, mvt::MVTSinkProvider,
serde::SerdeSinkProvider,
};
use nusamai::source::citygml::CityGMLSourceProvider;
use nusamai::source::citygml::CityGmlSourceProvider;
use nusamai::source::DataSourceProvider;
use nusamai::transformer::builder::{NusamaiTransformBuilder, TransformBuilder};
use nusamai::transformer::runner::MultiThreadTransformer;
Expand Down Expand Up @@ -38,7 +38,7 @@ fn run(input_paths: Vec<String>, output_path: String, filetype: String) {
let canceller = Arc::new(Mutex::new(Canceller::default()));

let source = {
let source_provider: Box<dyn DataSourceProvider> = Box::new(CityGMLSourceProvider {
let source_provider: Box<dyn DataSourceProvider> = Box::new(CityGmlSourceProvider {

Check warning on line 41 in app/src-tauri/src/main.rs

View check run for this annotation

Codecov / codecov/patch

app/src-tauri/src/main.rs#L41

Added line #L41 was not covered by tests
filenames: input_paths,
});
let mut source_params = source_provider.parameters();
Expand Down Expand Up @@ -75,7 +75,7 @@ fn run(input_paths: Vec<String>, output_path: String, filetype: String) {
};

let (transformer, schema) = {
use nusamai_citygml::CityGMLElement;
use nusamai_citygml::CityGmlElement;

Check warning on line 78 in app/src-tauri/src/main.rs

View check run for this annotation

Codecov / codecov/patch

app/src-tauri/src/main.rs#L78

Added line #L78 was not covered by tests
let transform_builder = NusamaiTransformBuilder::default();
let mut schema = nusamai_citygml::schema::Schema::default();
TopLevelCityObject::collect_schema(&mut schema);
Expand Down
10 changes: 5 additions & 5 deletions nusamai-citygml/macros/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub struct FooBarFeature {
It expands to:

```rust
#[derive(Default, Debug, CityGMLElement)]
#[derive(Default, Debug, CityGmlElement)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(tag = "type"))]
#[citygml(name = "abc:FooBarFeature")]
pub struct FooBarFeature {
Expand Down Expand Up @@ -66,7 +66,7 @@ pub struct FooBarData {
It expands to:

```rust
#[derive(Default, Debug, CityGMLElement)]
#[derive(Default, Debug, CityGmlElement)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(tag = "type"))]
#[citygml(name = "abc:FooBarData")]
pub struct FooBarFeature {
Expand All @@ -90,7 +90,7 @@ pub enum FooBarProperty {
It expands to:

```rust
#[derive(Default, Debug, CityGMLElement)]
#[derive(Default, Debug, CityGmlElement)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(tag = "type"))]
#[citygml(name = "abc:FooBarProperty")]
pub enum FooBarProperty {
Expand All @@ -105,9 +105,9 @@ pub enum FooBarProperty {

## Derive macros

### `#[derive(CityGMLElement)]`
### `#[derive(CityGmlElement)]`

It automatically implements the `CityGMLElement` trait for the target struct/enum, enabling it to parse corresponding CityGML fragments.
It automatically implements the `CityGmlElement` trait for the target struct/enum, enabling it to parse corresponding CityGML fragments.

In most cases, you should use the attribute macros above instead of directly applying this derive macro.

Expand Down
26 changes: 13 additions & 13 deletions nusamai-citygml/macros/src/derive.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! CityGMLElement derive macro
//! CityGmlElement derive macro
use proc_macro2::{Ident, TokenStream};
use quote::{format_ident, quote};
Expand Down Expand Up @@ -195,7 +195,7 @@ fn generate_citygml_impl_for_struct(
let pat = LitByteStr::new(path, attr.span());
let hash = hash(path);
child_arms.push(quote! {
(#hash, #pat) => <#field_ty as CityGMLElement>::parse(&mut self.#field_ident, st),
(#hash, #pat) => <#field_ty as CityGmlElement>::parse(&mut self.#field_ident, st),
});
};

Expand All @@ -216,7 +216,7 @@ fn generate_citygml_impl_for_struct(
);
prop_stmts.push(
quote! {
attributes.insert("gen:genericAttribute".into(), <#field_ty as CityGMLElement>::collect_schema(schema));
attributes.insert("gen:genericAttribute".into(), <#field_ty as CityGmlElement>::collect_schema(schema));
}
);
Ok(())
Expand All @@ -232,7 +232,7 @@ fn generate_citygml_impl_for_struct(
// XML attributes (e.g. @gml:id)
attribute_arms.push(quote! {
#path => {
self.#field_ident = <#field_ty as nusamai_citygml::CityGMLAttribute>::parse_attr_value(
self.#field_ident = <#field_ty as nusamai_citygml::CityGmlAttribute>::parse_attr_value(
std::str::from_utf8(value).unwrap(),
)?;
Ok(())
Expand All @@ -251,7 +251,7 @@ fn generate_citygml_impl_for_struct(
});
prop_stmts.push(
quote! {
attributes.insert(#name.into(), <#field_ty as CityGMLElement>::collect_schema(schema));
attributes.insert(#name.into(), <#field_ty as CityGmlElement>::collect_schema(schema));
}
);
}
Expand All @@ -269,7 +269,7 @@ fn generate_citygml_impl_for_struct(

let hash = hash(&path.value());
child_arms.push(quote! {
(#hash, #path) => <#field_ty as CityGMLElement>::parse(&mut self.#field_ident, st),
(#hash, #path) => <#field_ty as CityGmlElement>::parse(&mut self.#field_ident, st),
});

if !into_obj_generated {
Expand All @@ -289,12 +289,12 @@ fn generate_citygml_impl_for_struct(
prop_stmts.push(
match required {
true => quote! {
let mut ty_ref = <#field_ty as CityGMLElement>::collect_schema(schema);
let mut ty_ref = <#field_ty as CityGmlElement>::collect_schema(schema);
if ty_ref.min_occurs == 0 { ty_ref.min_occurs = 1; }
attributes.insert(#name.into(), ty_ref);
},
false => quote! {
attributes.insert(#name.into(), <#field_ty as CityGMLElement>::collect_schema(schema));
attributes.insert(#name.into(), <#field_ty as CityGmlElement>::collect_schema(schema));
}
}
);
Expand Down Expand Up @@ -374,7 +374,7 @@ fn generate_citygml_impl_for_struct(
};

Ok(quote! {
impl #impl_generics ::nusamai_citygml::CityGMLElement for #struct_ident #ty_generics #where_clause {
impl #impl_generics ::nusamai_citygml::CityGmlElement for #struct_ident #ty_generics #where_clause {
fn parse<R: std::io::BufRead>(&mut self, st: &mut ::nusamai_citygml::SubTreeReader<R>) -> Result<(), ::nusamai_citygml::ParseError> {
#attr_parsing

Expand Down Expand Up @@ -459,7 +459,7 @@ fn generate_citygml_impl_for_enum(
let field_ty = &field.ty;
let variant_ident = &variant.ident;
choice_types.push(quote! {
<#field_ty as CityGMLElement>::collect_schema(schema),
<#field_ty as CityGmlElement>::collect_schema(schema),
});

for attr in &variant.attrs {
Expand All @@ -476,7 +476,7 @@ fn generate_citygml_impl_for_enum(
quote! {
(_, #path) => {
let mut v: #field_ty = Default::default();
<#field_ty as CityGMLElement>::parse(&mut v, st)?;
<#field_ty as CityGmlElement>::parse(&mut v, st)?;
*self = Self::#variant_ident(v);
Ok(())
}
Expand All @@ -485,7 +485,7 @@ fn generate_citygml_impl_for_enum(
quote! {
(#hash, #path) => {
let mut v: #field_ty = Default::default();
<#field_ty as CityGMLElement>::parse(&mut v, st)?;
<#field_ty as CityGmlElement>::parse(&mut v, st)?;
*self = Self::#variant_ident(v);
Ok(())
}
Expand All @@ -505,7 +505,7 @@ fn generate_citygml_impl_for_enum(
let struct_name = &derive_input.ident;

Ok(quote! {
impl #impl_generics ::nusamai_citygml::CityGMLElement for #struct_name #ty_generics #where_clause {
impl #impl_generics ::nusamai_citygml::CityGmlElement for #struct_name #ty_generics #where_clause {
fn parse<R: ::std::io::BufRead>(&mut self, st: &mut ::nusamai_citygml::SubTreeReader<R>) -> Result<(), ::nusamai_citygml::ParseError> {
st.parse_children(|st| {
let path = st.current_path();
Expand Down
2 changes: 1 addition & 1 deletion nusamai-citygml/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mod type_attrs;

use proc_macro::TokenStream;

#[proc_macro_derive(CityGMLElement, attributes(citygml))]
#[proc_macro_derive(CityGmlElement, attributes(citygml))]
pub fn derive_citygml_element(token: TokenStream) -> TokenStream {
derive::derive_citygml_element(token)
}
Expand Down
42 changes: 22 additions & 20 deletions nusamai-citygml/macros/src/type_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub(crate) fn citygml_type(

quote! {
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(tag = "type"))]
#[derive(Default, Debug, ::nusamai_citygml::CityGMLElement)]
#[derive(Default, Debug, ::nusamai_citygml::CityGmlElement)]
#input
}
.into()
Expand Down Expand Up @@ -190,25 +190,27 @@ fn modify(ty: &StereoType, args: &FeatureArgs, input: &mut DeriveInput) -> Resul
);
pos += 1;

add_named_field(
pos,
fields,
quote! {
#[citygml(path = b"core:validFrom")]
pub valid_from: Option<::nusamai_citygml::Date> // TODO: DateTime (CityGML 3.0)
},
);
pos += 1;

add_named_field(
pos,
fields,
quote! {
#[citygml(path = b"core:validTo")]
pub valid_to: Option<::nusamai_citygml::Date> // TODO: DateTime (CityGML 3.0)
},
);
pos += 1;
// // CityGML 3.0
// add_named_field(
// pos,
// fields,
// quote! {
// #[citygml(path = b"core:validFrom")]
// pub valid_from: Option<::nusamai_citygml::Date> // TODO: DateTime (CityGML 3.0)
// },
// );
// pos += 1;
//
// // CityGML 3.0
// add_named_field(
// pos,
// fields,
// quote! {
// #[citygml(path = b"core:validTo")]
// pub valid_to: Option<::nusamai_citygml::Date> // TODO: DateTime (CityGML 3.0)
// },
// );
// pos += 1;

// TODO: not implemented yet
add_named_field(
Expand Down
8 changes: 4 additions & 4 deletions nusamai-citygml/src/attribute.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
use crate::parser::ParseError;

pub trait CityGMLAttribute: Sized {
pub trait CityGmlAttribute: Sized {
fn parse_attr_value(value: &str) -> Result<Self, ParseError>;
}

impl CityGMLAttribute for String {
impl CityGmlAttribute for String {
#[inline]
fn parse_attr_value(value: &str) -> Result<Self, ParseError> {
Ok(value.to_string())
}
}

impl<T: CityGMLAttribute> CityGMLAttribute for Option<T> {
impl<T: CityGmlAttribute> CityGmlAttribute for Option<T> {
#[inline]
fn parse_attr_value(value: &str) -> Result<Self, ParseError> {
Ok(Some(<T as CityGMLAttribute>::parse_attr_value(value)?))
Ok(Some(<T as CityGmlAttribute>::parse_attr_value(value)?))

Check warning on line 17 in nusamai-citygml/src/attribute.rs

View check run for this annotation

Codecov / codecov/patch

nusamai-citygml/src/attribute.rs#L17

Added line #L17 was not covered by tests
}
}
2 changes: 1 addition & 1 deletion nusamai-citygml/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub use values::*;

pub use object::Value;

pub trait CityGMLElement: Sized {
pub trait CityGmlElement: Sized {
/// Parse a XML fragment into this element.
fn parse<R: std::io::BufRead>(&mut self, st: &mut SubTreeReader<R>) -> Result<(), ParseError>;

Expand Down
21 changes: 21 additions & 0 deletions nusamai-citygml/src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,27 @@ pub enum Value {
Object(Object),
}

impl Value {
/// Traverses the attribute tree and apply the function to each object.
pub fn traverse_object_mut(&mut self, mut f: impl FnMut(&mut Object)) {
self.traverse_object_mut_inner(&mut f);
}

fn traverse_object_mut_inner(&mut self, f: &mut impl FnMut(&mut Object)) {
match self {
Value::Object(obj) => {
f(obj);
}
Value::Array(arr) => {
for v in arr.iter_mut() {
v.traverse_object_mut_inner(f);
}

Check warning on line 76 in nusamai-citygml/src/object.rs

View check run for this annotation

Codecov / codecov/patch

nusamai-citygml/src/object.rs#L73-L76

Added lines #L73 - L76 were not covered by tests
}
_ => {}

Check warning on line 78 in nusamai-citygml/src/object.rs

View check run for this annotation

Codecov / codecov/patch

nusamai-citygml/src/object.rs#L78

Added line #L78 was not covered by tests
}
}
}

#[cfg(feature = "serde_json")]
impl Value {
/// Extracts the thematic attribute tree and converts it to a JSON representation.
Expand Down
6 changes: 3 additions & 3 deletions nusamai-citygml/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub enum ParseError {
Cancelled,
}

pub struct CityGMLReader<'a> {
pub struct CityGmlReader<'a> {
state: InternalState<'a>,
}

Expand Down Expand Up @@ -100,7 +100,7 @@ impl<'a> Default for ParseContext<'a> {
}
}

impl<'a> CityGMLReader<'a> {
impl<'a> CityGmlReader<'a> {
#[inline]
pub fn new(context: ParseContext<'a>) -> Self {
Self {
Expand Down Expand Up @@ -816,7 +816,7 @@ mod tests {

fn parse(doc: &str, f: impl Fn(&mut SubTreeReader<std::io::Cursor<&str>>)) {
let mut reader = quick_xml::NsReader::from_reader(std::io::Cursor::new(doc));
let mut citygml_reader = CityGMLReader::new(ParseContext::default());
let mut citygml_reader = CityGmlReader::new(ParseContext::default());
let mut subtree_reader = citygml_reader
.start_root(&mut reader)
.expect("Failed to start root");
Expand Down
10 changes: 5 additions & 5 deletions nusamai-citygml/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub struct PropertyTypeDef {
pub struct Attribute {
#[serde(rename = "ref")]
pub type_ref: TypeRef,
#[serde(default, skip_serializing_if = "is_one")]
#[serde(default, skip_serializing_if = "is_zero")]
pub min_occurs: u16,
#[serde(default, skip_serializing_if = "is_some_one")]
pub max_occurs: Option<u16>,
Expand All @@ -61,7 +61,7 @@ impl Default for Attribute {
fn default() -> Self {
Self {
type_ref: TypeRef::Unknown,
min_occurs: 1,
min_occurs: 0,
max_occurs: Some(1),
}
}
Expand All @@ -88,13 +88,13 @@ fn is_false(n: &bool) -> bool {
!(*n)
}

fn is_one(n: &u16) -> bool {
*n == 1
fn is_zero(n: &u16) -> bool {
*n == 0

Check warning on line 92 in nusamai-citygml/src/schema.rs

View check run for this annotation

Codecov / codecov/patch

nusamai-citygml/src/schema.rs#L91-L92

Added lines #L91 - L92 were not covered by tests
}

fn is_some_one(n: &Option<u16>) -> bool {
match n {
Some(n) => is_one(n),
Some(n) => *n == 1,

Check warning on line 97 in nusamai-citygml/src/schema.rs

View check run for this annotation

Codecov / codecov/patch

nusamai-citygml/src/schema.rs#L97

Added line #L97 was not covered by tests
None => false,
}
}
Loading

0 comments on commit d9b6368

Please sign in to comment.