<?xml version="1.0" encoding="UTF-8"?>
<?asciidoc-toc maxdepth="2"?>
<?asciidoc-numbered?>
<article xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en">
<info>
<title>csdif-core</title>
<date>2025-10-12</date>
<author>
<personname>
<firstname>Egon</firstname>
<surname>Kastelijn</surname>
</personname>
</author>
<authorinitials>EK</authorinitials>
</info>
<simpara>๐ฆ Core library for modeling, validating, and transforming CSDIF data.</simpara>
<section xml:id="_purpose">
<title>๐ง Purpose</title>
<simpara>This crate provides the reusable core logic for working with CSDIF data structures. It is designed to be used by multiple adapters, including:</simpara>
<itemizedlist>
<listitem>
<simpara><literal>csdif-cli</literal> โ command-line exporter</simpara>
</listitem>
<listitem>
<simpara><literal>csdif-api</literal> โ web-based API service</simpara>
</listitem>
</itemizedlist>
<simpara>It implements the format and validation layer of the CSDIF RFC, but does not include any I/O, CLI, or web-specific logic.</simpara>
</section>
<section xml:id="_design_pattern">
<title>๐งฑ Design Pattern</title>
<simpara>This crate represents the <emphasis role="strong">core hexagon</emphasis> in a hexagonal architecture (Ports & Adapters). It contains:</simpara>
<itemizedlist>
<listitem>
<simpara>Domain models (<literal>Sensor</literal>, <literal>Observation</literal>, <literal>Location</literal>, <literal>CsdifDocument</literal>)</simpara>
</listitem>
<listitem>
<simpara>Validation logic (<literal>validate_document</literal>)</simpara>
</listitem>
<listitem>
<simpara>Transformation and mapping functions</simpara>
</listitem>
</itemizedlist>
<simpara>Adapters such as CLI or web-API interact with this crate via public interfaces, but this crate remains unaware of its consumers.</simpara>
</section>
<section xml:id="_features">
<title>๐ฆ Features</title>
<itemizedlist>
<listitem>
<simpara>โ
CSDIF-compliant data structures</simpara>
</listitem>
<listitem>
<simpara>โ
JSON serialization and deserialization</simpara>
</listitem>
<listitem>
<simpara>โ
Validation of document structure and semantics</simpara>
</listitem>
<listitem>
<simpara>โ
Mapping and transformation helpers</simpara>
</listitem>
<listitem>
<simpara>โ No I/O, CLI, or async dependencies</simpara>
</listitem>
</itemizedlist>
</section>
<section xml:id="_data_processing_flow">
<title>Data Processing Flow</title>
<simpara>Incoming CS-DIF data passes through the following stages:</simpara>
<informaltable frame="all" rowsep="1" colsep="1">
<tgroup cols="4">
<colspec colname="col_1" colwidth="25*"/>
<colspec colname="col_2" colwidth="25*"/>
<colspec colname="col_3" colwidth="25*"/>
<colspec colname="col_4" colwidth="25*"/>
<thead>
<row>
<entry align="left" valign="top">Step</entry>
<entry align="left" valign="top">Description</entry>
<entry align="left" valign="top">Responsible Component</entry>
<entry align="left" valign="top">Extensibility</entry>
</row>
</thead>
<tbody>
<row>
<entry align="left" valign="top"><simpara>1. Transport (Inbound)</simpara></entry>
<entry align="left" valign="top"><simpara>Data arrives via HTTP, MQTT, File, etc.</simpara></entry>
<entry align="left" valign="top"><simpara>csdif-api, csdif-mqtt, csdif-cli</simpara></entry>
<entry align="left" valign="top"><simpara>Add new transport modules</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>2. Format Decoding</simpara></entry>
<entry align="left" valign="top"><simpara>Raw data is decoded from JSON, XML, CSV, etc.</simpara></entry>
<entry align="left" valign="top"><simpara>csdif-core::format</simpara></entry>
<entry align="left" valign="top"><simpara>Implement new FormatDecoder traits</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>3. Schema Interpretation</simpara></entry>
<entry align="left" valign="top"><simpara>Data is interpreted according to the initiative-specific schema</simpara></entry>
<entry align="left" valign="top"><simpara>csdif-mapper-*</simpara></entry>
<entry align="left" valign="top"><simpara>Implement InitiativeMapper trait</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>4. Mapping to SensorML</simpara></entry>
<entry align="left" valign="top"><simpara>Data is converted into the internal SensorML domain model</simpara></entry>
<entry align="left" valign="top"><simpara>csdif-mapper-* + sensorml</simpara></entry>
<entry align="left" valign="top"><simpara>Add new mappers per initiative</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>5. Validation & Processing</simpara></entry>
<entry align="left" valign="top"><simpara>SensorML document is validated and optionally enriched</simpara></entry>
<entry align="left" valign="top"><simpara>sensorml</simpara></entry>
<entry align="left" valign="top"><simpara>Extend domain validation via traits</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>6. Mapping to External Schema (optional)</simpara></entry>
<entry align="left" valign="top"><simpara>SensorML is transformed into a target schema if needed</simpara></entry>
<entry align="left" valign="top"><simpara>csdif-core::mapper::*</simpara></entry>
<entry align="left" valign="top"><simpara>Implement SchemaExporter trait</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>7. Format Encoding</simpara></entry>
<entry align="left" valign="top"><simpara>Data is encoded into JSON, XML, CSV, etc.</simpara></entry>
<entry align="left" valign="top"><simpara>csdif-core::format</simpara></entry>
<entry align="left" valign="top"><simpara>Implement FormatEncoder traits</simpara></entry>
</row>
<row>
<entry align="left" valign="top"><simpara>8. Transport (Outbound)</simpara></entry>
<entry align="left" valign="top"><simpara>Data is sent via HTTP, MQTT, File, etc.</simpara></entry>
<entry align="left" valign="top"><simpara>csdif-api, csdif-mqtt, csdif-cli</simpara></entry>
<entry align="left" valign="top"><simpara>Add new transport modules</simpara></entry>
</row>
</tbody>
</tgroup>
</informaltable>
<simpara>This layered architecture ensures that new formats, transports, or initiative-specific schemas can be added without modifying the core logic. Each layer is pluggable and testable in isolation.</simpara>
</section>
<section xml:id="_testing_philosophy">
<title>๐งช Testing Philosophy</title>
<itemizedlist>
<listitem>
<simpara>All logic is covered by unit tests</simpara>
</listitem>
<listitem>
<simpara>No <literal>unwrap</literal>, <literal>?</literal>, or <literal>panic!</literal> allowed</simpara>
</listitem>
<listitem>
<simpara>Errors are handled explicitly and surfaced clearly</simpara>
</listitem>
<listitem>
<simpara>JSON roundtrip tests ensure format stability</simpara>
</listitem>
<listitem>
<simpara>Validation logic is tested with both valid and invalid cases</simpara>
</listitem>
</itemizedlist>
</section>
<section xml:id="_license">
<title>๐ License</title>
<simpara>All source files include:</simpara>
<programlisting language="rust" linenumbering="unnumbered">// SPDX-License-Identifier: MIT</programlisting>
</section>
<section xml:id="_usage">
<title>๐ Usage</title>
<simpara>Add to your <literal>Cargo.toml</literal>:</simpara>
<programlisting language="toml" linenumbering="unnumbered">csdif-core = { git = "https://github.com/your-org/csdif-core", branch = "main" }</programlisting>
<simpara>Or use crates.io once published:</simpara>
<programlisting language="toml" linenumbering="unnumbered">csdif-core = "0.1.0"</programlisting>
<simpara>Then in your code:</simpara>
<programlisting language="rust" linenumbering="unnumbered">use csdif_core::{CsdifDocument, validate_document};</programlisting>
</section>
<section xml:id="_related_crates">
<title>๐ Related Crates</title>
<itemizedlist>
<listitem>
<simpara><literal>csdif-cli</literal>: CLI tool for exporting and validating CSDIF documents</simpara>
</listitem>
<listitem>
<simpara><literal>csdif-api</literal>: Web service exposing CSDIF validation and transformation endpoints</simpara>
</listitem>
</itemizedlist>
</section>
</article>