qntfy / kazaam

Arbitrary transformations of JSON in Golang
MIT License
281 stars 54 forks source link

Conditional Path Expressions and Chained Conversion Functions #89

Open mbordner opened 5 years ago

mbordner commented 5 years ago

Hello all. I love your library, but I needed the ability to convert values as well as having a bit of conditional logic to decide whether values would be mapped based on the values of other values in the JSON document.

I put together a feature change that supports inline JSON Path Expressions for conditional branching and conversion of values, and would be curious if this would be something welcomed into the project?

Use case: let's say I had a JSON document with the following money value: { "annual_revenue": "$1,000,000" } and I wanted the output to be: {"agr":"1000000.00"} if the field existed, or {"agr":"0.00"} if it did not.

The above example could be achieved with:

{
  "operation": "shift",
  "converters": {
    "regex": {
      "remove_dollar_sign": {
        "match": "\\$?\\s*(.*)",
        "replace": "$1"
      },
      "remove_comma": {
        "match": ",",
        "replace": ""
      }
    }
  },
  "spec": {
    "agr": "annual_revenue ? \"0.00\" | regex remove_dollar_sign | regex remove_comma | ston | format %.2f"
  }
}

I've updated the documentation with syntax examples for all of the Converters that I added, and have the feature built out with tests in this same commit:

https://github.com/mbordner/kazaam/blob/feature/value-conditional-and-converter-expressions/README.md#json-path-parameters

https://github.com/mbordner/kazaam/blob/feature/value-conditional-and-converter-expressions/README.md#converter-specification-support

Another example: Say, I want to change the state name from Ohio to OH in the following document: {"state":"Ohio"} to produce: {"state":"OH"}

I could achieve this with:

{
  "operation": "shift",
  "converters": {
    "mapped": {
      "states": {
        "Ohio": "OH",
        "Texas": "TX"
      }
    }
  },
  "spec": {
    "state": "state | mapped states"
  }
}

or with

{
  "operation": "shift",
  "spec": {
    "state": "state | upper | substr 0 2"
  }
}
StratusBase commented 5 years ago

I need this!!!

mbordner commented 5 years ago

i needed this for 1) data type conversions 2) logic in determining whether to leave off paths in the transform 3) default values

I kept a branch in case i should send a PR back to this, but moving forward so that I can use these features, I've changed the paths to point to this fork and it should be usable for now at:

https://github.com/mbordner/kazaam

JoshuaC215 commented 5 years ago

Hey @mbordner thank you for raising this and your patience with the slow response. We have been resistant to adding this sort of thing to the core library just to keep it simpler. I think for now keeping in your fork is a good move. Our development on this project has slowed but if we start adding new features where you need to merge this in to take advantage in the future, more than happy to revisit and work with you to get it added.

mainpart commented 2 years ago

as of apr 2022 fork not works with default examples https://go.dev/play/p/o6ror2BPQt3