georust / geojson

Library for serializing the GeoJSON vector GIS file format
https://crates.io/crates/geojson
Apache License 2.0
276 stars 60 forks source link

Add macros to ease the creation of structures #192

Open frewsxcv opened 2 years ago

frewsxcv commented 2 years ago

(copied from discord)

what do people think about adding macros in the geojson crate to ease creation?

let feature = geojson::feature! {
   geometry: geojson::point![1., 1.],
   properties: {
      foo: "bar",
   },
};

versus

let properties = HashMap::<String, serde_json::JsonValue>::new():
properties.insert("foo".to_string(), "bar".to_string());
let feature = geojson::Feature {
   geometry: Some(geojson::Geometry::new(
      geojson::Value::Point(vec![1., 1.,]),
   )),
   properties: Some(properties),
   ...Default::default(),
};

not the exact syntax necessarily. just think it would be great to have an easier way to construct the structures

it'd be really slick if the body of the macro was identical syntax to geojson

lnicola commented 2 years ago

I'm not a fan, TBH. Macros are a different, library-specific language, are not discoverable (you need to read the docs or the implementation instead of relying on auto-complete), and can interact poorly with IDEs.

They're fine as an alternative, but I wouldn't want todl deprecate the current approach.

frewsxcv commented 2 years ago

are not discoverable (you need to read the docs or the implementation instead of relying on auto-complete)

Screen Shot 2022-05-31 at 8 30 10 AM
frewsxcv commented 2 years ago

And no plans to deprecate the public fields in the structs, if users want to create them that way.

michaelkirk commented 2 years ago

Macros are a different, library-specific language, are not discoverable

I can understand this criticism of macros in general. I think it's less problematic here, because I'm hoping that the "library specific language" we use in this case is geojson. I'm not sure if it's viable, but I was envisioning something like theserde_json::json! macro, which is used like this:

// The type of `john` is `serde_json::Value`
let john = json!({
    "name": "John Doe",
    "age": 43,
    "phones": [
        "+44 1234567",
        "+44 2345678"
    ]
});

Yes that macro is using a DSL - but the DSL is JSON. I think it's pretty reasonable for people generating JSON to understand how to read/write JSON. So I'm imagining something like that, but it would be more restrictive than serde_json::json! in that it only accepts valid geojson.

I too am in favor of keeping the idiomatic verbose rust way of building all these structures for those that prefer it. Presumably any DSL would ultimately be built on top of those things anyway.