CJM v0.4.0
CJM v0.4.0 Release Notes
CJM v0.4.0 expands the practical mapping surface and introduces the first
generated model-contract metadata for downstream tools.
This release keeps CJM focused on strongly typed, structured, modelable JSON.
It does not add arbitrary dynamic JSON support, custom converters, native JSON
runtime code, or automatic header discovery.
Highlights
- Adds
std::array<T, N>support for supported element types - Serializes supported
enumandenum classfields as JSON strings - Generates enum string conversion helpers in the nlohmann backend
- Exposes enum value metadata through generated model-contract descriptors
- Adds generated model-contract type descriptors for arrays, maps, optionals,
vectors, objects, enums, and scalar categories - Improves CLI ergonomics for grouped explicit
--inputheaders - Clarifies downstream generated artifact handles through
cjm_generate - Documents custom converter boundaries without implementing converters
- Documents high-performance backend strategy and keeps native JSON engine work
outside the CJM v1.0 critical path
Mapping Additions
std::array<T, N> maps to a JSON array when T is already supported.
Supported enum fields map to JSON strings by default:
enum class Status {
Active,
Disabled,
};
struct User {
Status status; // json:"status"
};The generated nlohmann backend writes:
{"status":"Active"}Unknown enum strings fail through the generated conversion helper.
Custom enum rename policies, enum aliases, case conversion policies, and
numeric enum mode are not implemented in v0.4.
Downstream Workflow
The recommended CMake workflow remains:
cjm_generate(
TARGET app
HEADERS user.hpp
)For multiple explicit model headers:
cjm_generate(
TARGET app
HEADERS
address.hpp
user.hpp
)The current CMake integration generates one *.cjm.hpp per listed header under
the build directory's generated/cjm include directory.
CJM does not automatically discover #include dependencies yet. Pass each
model header explicitly.
Manual CLI users can group related inputs into one generated output:
cjm generate \
--input address.hpp user.hpp \
--output model.cjm.hppRepeating --input remains supported:
cjm generate \
--input address.hpp \
--input user.hpp \
--output model.cjm.hppGenerated Model Contract
Generated headers include experimental model-contract metadata through:
cjm::contract::model_traits<T>::modelThe v0.4 contract exposes:
- model names
- field names
- JSON names
- ignored fields
omitempty- source locations
- type categories
- container type arguments
- enum string values
This contract is intended for downstream experiments such as schema generation,
typed endpoint tooling, documentation, and CLI/RPC binders. It may still change
before v1.0.
Custom Converter Boundary
v0.4 documents custom converter boundaries but does not implement converters.
Domain-specific scalar types such as UUID, decimal, path, duration, and
project-specific identifiers should eventually use explicit converter metadata
instead of becoming unlimited built-in mappings.
Converters are not a dynamic JSON escape hatch. std::any, arbitrary dynamic
JSON documents, pointer ownership policies, polymorphism, and std::variant
without a discriminator policy remain out of scope.
Known Limitations
Not yet supported:
- arbitrary JSON values
std::variantstd::any- pointer fields
- polymorphism
- custom converters
- custom enum string mapping policies
- time and datetime mappings
- automatic header discovery
- full C++ grammar support at the CJM product level
- multiline managed field declarations are not yet documented as supported
- private fields
- native JSON backend
- install/package distribution
Verification
The release branch should be verified with:
cmake --build build
ctest --test-dir build --output-on-failureTag
Release tag:
v0.4.0