Rust, C# and C++ change their property API. Those three stored every value
as a string, so they serialized differently from Python, JS and TS - one
graph produced two different documents depending on which language wrote
it. They now use their parser's own value type.
Changed — breaking (Rust, C#, C++ only)
-
Properties carry types.
HashMap<String, String>becomes
HashMap<String, ison_rs::Value>,Dictionary<string, string>becomes
Dictionary<string, object?>, andmap<string, string>becomes
map<string, ison::Value>. Not a new union - the parser already models
exactly the types the format has, and keeping a second one beside it is
what caused the split.# 1.3.0 (Rust, C#, C++) # 1.4.0 - matching Python/JS/TS nodes.company nodes.company id listed name staff id listed name staff acme "false" "Acme" "42" acme false "Acme Corp" 42 -
Rust callers use
props!. AVecis homogeneous, so a literal mixing
an int and a string cannot be written directly, and the orphan rule stops
this crate addingFromimpls toison_rs::Value.props![("name", "Acme"), ("staff", 42i64)]converts each value before collecting.
vec![("k", "v")]no longer compiles for properties. -
A number now compares as a number in queries, rather than as a parse
of its rendering. A string holding a number still compares numerically,
so filters written against the old storage keep working. Schema
validation is unchanged - it still validates the rendered text; making it
type-aware is a separate change.
Fixed
-
The three string-only ports round-trip values without flattening them.
Loading42gave back the string"42", which then re-emitted quoted. -
schema-generatoremitted Python that could not run. It imported
StringField/IntField/FloatField/BoolField- the names the Rust, JS,
TS, C# and C++ ports use - where Python hasString/Int/Float/Bool;
it called.min_length()/.max_length(), spelled.min()/.max()on
Python'sString; it called the singular.node_type()/.edge_type();
and it chained across lines without brackets, so the output was a syntax
error regardless. Its tests asserted substrings and so passed throughout;
they now execute the generated code.
Known limitation
- An integral float originated in JavaScript or TypeScript cannot be
distinguished from an integer.1.0 === 1in JS, so a JS-authored
{weight: 1.0}emits1where Python emits1.0. This is a property of
the language, not of ISONGraph. Values arriving from ISON keep their
form in every port; only origination is affected. The shared test fixture
deliberately contains no integral float for this reason.
Install
pip install ison-graph==1.4.0
cargo add ison-graph@1.4.0
npm install ison-graph-js@1.4.0 # or ison-graph-ts@1.4.0
dotnet add package IsonGraph --version 1.4.0C++ is header-only: copy ison-graph-cpp/include/ison_graph.hpp. It needs
ison-cpp >= 1.2.0 on the include path.
All six ports serialize identically; the shared fixture is 488 bytes ISON,
636 bytes ISONL.