Sidereon.CCSDS.TDM (Sidereon v3.0.0)

Copy Markdown View Source

Parse and encode CCSDS Tracking Data Messages (TDM) in KVN format.

Date/time fields are preserved as raw strings. Data record values carry both the parsed float and the original decimal token so KVN round-trips do not rewrite measurement text. Comments keep their place among the fields and records they sit between (Sidereon.CCSDS.TDM.Comment) and are written back there.

Strict and policy entries

parse_kvn/1 and encode_kvn/1 hold a message to CCSDS 503.0-B-2 and refuse any departure by name. parse_kvn_with_policy/2 reads under a Sidereon.CCSDS.TDM.Policy that may forgive departures which do not change what a value means, and returns every one it forgave as a Sidereon.CCSDS.TDM.Warning; encode_kvn_with_policy/2 writes under a Sidereon.CCSDS.TDM.WritePolicy and returns every departure it emitted as a Sidereon.CCSDS.TDM.Departure. Nothing that changes what the message means is forgiven under any policy.

Metadata

A metadata block's ordered raw fields are its authority. Its participants, mode, paths, timetag reference, time system and range units are derived from them, and the writer emits the fields and derives from them again. Build or change a block with Sidereon.CCSDS.TDM.Metadata.from_raw/2, from_raw_with_policy/3, replace_raw/3 or replace_raw_with_policy/4, which derive every property from the fields in one step. A block whose derived properties were edited apart from its fields is refused by the encoders as {:metadata_not_derived, %{segment, property}} rather than written as the fields say.

Refusals

Every refusal is {:error, {tag, fields}}, fields a map holding every field the refusal carries:

  • {:no_segments, %{}}
  • {:section, %{line, detail}}
  • {:malformed_line, %{line, text}}
  • {:non_printable_character, %{line, keyword, column, character}}
  • {:line_too_long, %{line, keyword, length}}
  • {:malformed_epoch, %{line, keyword, text}}
  • {:records_out_of_order, %{segment, keyword, epoch}}
  • {:duplicate_record, %{segment, keyword, epoch}}
  • {:unterminated_final_line, %{line}}
  • {:unwritable, %{keyword, reason}} - a field or comment the KVN form cannot carry, or a comment position or order the writer cannot emit unchanged.
  • {:keyword_out_of_order, %{line, keyword, section}}
  • {:undefined_participant, %{segment, keyword, index}}
  • {:conflicting_keyword, %{line, keyword, section, first, second}}
  • {:repeated_keyword, %{line, keyword, section}}
  • {:undefined_keyword, %{line, keyword, section}}
  • {:missing_keyword, %{keyword, segment}} - segment is nil for the header. An absent CCSDS_TDM_VERS is refused this way too.
  • {:empty_data_section, %{segment}}
  • {:empty_value, %{line, keyword}}
  • {:invalid_version, %{line, value}}
  • {:keyword_not_assignable, %{keyword}}
  • {:malformed_record, %{line, keyword}}
  • {:invalid_field, %{keyword, kind}} - kind is one of :missing, :float_parse, :non_finite, :not_positive, :out_of_range, :invalid_index, :unknown_keyword, :unexpected_unit, :non_integer, :negative, :negative_zero, :unit_mismatch and :decimal_mismatch, or the core's own text for a kind this binding predates.
  • {:metadata_not_derived, %{segment, property}} - see "Metadata".
  • {:unhandled, %{message}} - a refusal this binding predates, with the core's own text; no other tag stands in for it.

line is the one-based input line, nil where the writer raises the refusal for a line no input produced. segment is one-based. section is :header, :metadata or :data. character is a one-character string.

A value that cannot cross into the boundary is refused before the call as {:invalid_tdm_field, field, value}: a comment position or participant index that is not a non-negative integer in the range the boundary carries it in, or a record value that is not a number a double holds.

Summary

Types

A refusal, {tag, fields}, as the moduledoc lists them.

t()

Functions

Encode a TDM as KVN text under the strict policy.

Encode a TDM as KVN text under the strict policy, which emits no departure from CCSDS 503.0-B-2.

Encode a TDM as KVN text under a writer policy.

Parse a TDM KVN document under the strict policy.

Parse a TDM KVN document under the strict policy, which forgives nothing.

Parse a TDM KVN document under a reader policy.

Types

error()

@type error() :: {atom(), map()} | {:invalid_tdm_field, atom(), term()}

A refusal, {tag, fields}, as the moduledoc lists them.

t()

@type t() :: %Sidereon.CCSDS.TDM{
  comments: [Sidereon.CCSDS.TDM.Comment.t()],
  creation_date: String.t() | nil,
  header_fields: [Sidereon.CCSDS.TDM.Field.t()],
  message_id: String.t() | nil,
  originator: String.t() | nil,
  segments: [Sidereon.CCSDS.TDM.Segment.t()],
  version: String.t()
}

Functions

encode(tdm)

@spec encode(t()) :: {:ok, String.t()} | {:error, error()}

Encode a TDM as KVN text under the strict policy.

encode_kvn(tdm)

@spec encode_kvn(t()) :: {:ok, String.t()} | {:error, error()}

Encode a TDM as KVN text under the strict policy, which emits no departure from CCSDS 503.0-B-2.

The writer holds the value to the rules the reader holds a message to and refuses what it cannot write conformingly and unchanged, comments included. Returns {:ok, text} or {:error, {tag, fields}}.

encode_kvn_with_policy(tdm, policy)

@spec encode_kvn_with_policy(
  t(),
  Sidereon.CCSDS.TDM.WritePolicy.t() | keyword() | map()
) ::
  {:ok, %{value: String.t(), departures: [Sidereon.CCSDS.TDM.Departure.t()]}}
  | {:error, term()}

Encode a TDM as KVN text under a writer policy.

policy is a Sidereon.CCSDS.TDM.WritePolicy, or a keyword list or map of its axes. Returns {:ok, %{value: text, departures: departures}}, departures holding every departure from CCSDS 503.0-B-2 the writer emitted, as Sidereon.CCSDS.TDM.Departure structs; an empty list means the text conforms. What the policy does not allow is refused as {:error, {tag, fields}}.

parse(text)

@spec parse(String.t()) :: {:ok, t()} | {:error, error()}

Parse a TDM KVN document under the strict policy.

parse_kvn(text)

@spec parse_kvn(String.t()) :: {:ok, t()} | {:error, error()}

Parse a TDM KVN document under the strict policy, which forgives nothing.

Returns {:ok, tdm} or {:error, {tag, fields}}.

parse_kvn_with_policy(text, policy)

@spec parse_kvn_with_policy(
  String.t(),
  Sidereon.CCSDS.TDM.Policy.t() | keyword() | map()
) ::
  {:ok, %{value: t(), warnings: [Sidereon.CCSDS.TDM.Warning.t()]}}
  | {:error, term()}

Parse a TDM KVN document under a reader policy.

policy is a Sidereon.CCSDS.TDM.Policy, or a keyword list or map of its axes. Returns {:ok, %{value: tdm, warnings: warnings}}, warnings holding every departure the policy forgave, in reader order, as Sidereon.CCSDS.TDM.Warning structs; an empty list means the message departed from nothing. A departure the policy does not forgive is refused as {:error, {tag, fields}}, and a policy that does not read is refused as Sidereon.CCSDS.TDM.Policy documents.