Releases: TelemetryWorks/irig106-time
Releases · TelemetryWorks/irig106-time
v0.7.0
[v0.7.0] - 2026-03-29
⚠️ BREAKING CHANGES
-
AbsoluteTimerestructured withu64internal representation (P4-04) — Fields are now accessed via methods instead of direct field access. The internal representation is a singleu64(nanoseconds since start of day 1), makingadd_nanos/sub_nanossingle arithmetic operations on the common path.Migration guide:
- Field reads:
t.hours→t.hours(),t.day_of_year→t.day_of_year(),t.nanoseconds→t.nanoseconds(), etc. - Optional fields:
t.year→t.year() - Field mutations:
t.year = Some(2025)→AbsoluteTime::new(...).unwrap().with_year(Some(2025)).unwrap() - Struct literals:
AbsoluteTime { day_of_year: 100, hours: 12, ... }→AbsoluteTime::new(100, 12, ...)
- Field reads:
-
AbsoluteTimeno longer holds calendar metadata — Themonth,day_of_month,set_month(),set_day_of_month(), andwith_date()APIs have been removed. Calendar date information is now carried by the newCalendarTimetype, which enforces that year, month, and day are all present and valid at construction time. This eliminates the class of bugs where partial calendar state (e.g., month set without day) could be constructed.Migration guide:
t.month()/t.day_of_month()→ useCalendarTimeinstead ofAbsoluteTimet.set_month(Some(3))/t.set_day_of_month(Some(15))→CalendarTime::new(t, 3, 15)?t.with_date(2025, 3, 15)?→CalendarTime::from_parts(2025, 3, 15, doy, h, m, s, ns)?DmyFormatTime::to_absolute()→DmyFormatTime::to_calendar_time()(returnsCalendarTime)From<NaiveDateTime> for AbsoluteTime→From<NaiveDateTime> for CalendarTimeCalendarTimeimplementsDeref<Target=AbsoluteTime>, so allAbsoluteTimemethods work directly onCalendarTimevalues- To convert back:
let abs: AbsoluteTime = calendar_time.into();
Added
CalendarTimetype (L3-ABS-006) — Calendar-aware absolute time with validated year, month, and day-of-month. WrapsAbsoluteTimewithDeref<Target=AbsoluteTime>. Constructed viaCalendarTime::new(abs_time, month, day)orCalendarTime::from_parts(year, month, day, doy, h, m, s, ns). Enforces at the type level that calendar metadata is either fully present and valid, or absent entirely.DmyFormatTime::to_calendar_time()— Replacesto_absolute()for DMY BCD format. ReturnsCalendarTimewith validated year/month/day.From<CalendarTime> for chrono::NaiveDateTime— Direct conversion using validated month/day fields.From<chrono::NaiveDateTime> for CalendarTime— chrono always provides full date, so this returnsCalendarTime(wasAbsoluteTime).AbsoluteTime::as_total_ns()— Exposes the raw internal nanosecond count for efficient comparison and serialization.AbsoluteTime::with_year()— Consuming builder method that enriches a DOY timestamp with year metadata (0–9999). ReturnsResult<Self>for chaining:AbsoluteTime::new(...).unwrap().with_year(Some(2025)).unwrap(). Year is metadata, not a calendar invariant — seeCalendarTimefor full date validation.- UDP framing documentation (P5-03) — New
docs/udp_framing.mddocumenting that UDP Transfer Format 1 and 2 headers carry no time fields, and how to useStreamingTimeCorrelatorfor live UDP streams. - WASM build verification (P6-06) — CI now verifies
wasm32-unknown-unknowncompilation with--no-default-featuresand--no-default-features --features serde. utilmodule (P6-08) — Crate-internalis_leap_yearandabs_diff_u64helpers that replaceu16::is_multiple_of(Rust 1.87) andu64::abs_diff(Rust 1.60) respectively. Each carries a targeted#[allow(clippy::...)]and full MSRV dependency documentation. 18 unit tests covering leap year rules (common, century, quad-century, edge cases, IRIG 106 era years) and abs_diff properties (symmetry, extremes, leap second timestamps).- 11 new integration tests in
tests/pipeline.rs: leap year rollover throughsub_nanos(leap, non-leap, century, quad-century), BCD DMY Feb 29 on leap/non-leap years,is_near_leap_secondviaabs_diff_u64(exact boundary, within window, outside, symmetry, far future).
Changed
AbsoluteTimeinternal representation (P4-04) — Singleu64replaces 5 numeric fields.add_nanosis now a singleu64addition (was 4-level carry chain).sub_nanosyear rollover is cleaner arithmetic.total_nanos_of_day()is a single modulo operation.- Custom serde for
AbsoluteTime— Serializes to the same expanded JSON shape as v0.6 (day_of_year,hours,minutes,seconds,nanoseconds,year,month,day_of_month) for backward compatibility. Deserializes and recomposes theu64internally. - GitHub Actions CI — Added
wasm32-unknown-unknownbuild job. Separated stable (fullcargo test) from MSRV 1.60 (cargo checkonly — dev-dependencies require newer Rust). Tests 4 feature combos on stable + WASM + MSRV check. Cargo.toml— Version bumped to 0.7.0. MSRV lowered from 1.87 to 1.60.- CLI (irig106-time-cli) — Version bumped to 0.7.0. All
AbsoluteTimefield accesses migrated to methods. - MSRV lowered from 1.87 → 1.60 (P6-08) — Replaced
u16::is_multiple_of(Rust 1.87) withutil::is_leap_yearandu64::abs_diff(Rust 1.60) withutil::abs_diff_u64. The MSRV is now constrained bydep:namespaced features inCargo.toml(Rust 1.60). Each helper carries a targeted clippy#[allow]and full documentation of the API it replaces, the Rust version it avoids, and when it can be upgraded. - API audit — Added
Hashto 25 public types, enabling use asHashMapkeys andHashSetmembers. AddedCopytoTimeJumpandRtcReset.AbsoluteTimeintentionally omitsOrdbecause derivedPartialEqcompares all fields including optional year metadata; callers needing within-year ordering should useas_total_ns().TimeQualityomitsHash/Eq(containsf64). - Documentation — All code examples in
usage.mdupdated for method-based access. Version refs0.6→0.7across all docs. - All consumer modules migrated:
bcd.rs,chrono_interop.rs,network_time.rs,correlation.rs,quality.rs,streaming.rs, and all test files. - Total test count: 269 (184 unit + 68 integration + 17 property).
v0.6.0
[v0.6.0] - 2026-03-29
Added
streamingmodule (P5-02) —StreamingTimeCorrelatorwith sliding-window eviction for live UDP stream processing. Per-channelBTreeMapindex with O(log n) lookup. Configurablemax_age_nswindow with automatic eviction of stale references. Methods:add_reference,add_reference_f2,correlate,evict,len,is_empty,total_evicted,max_age_ns,latest_rtc,channel_ids,channel_len.StreamingRefstruct for reference points.qualitymodule (P5-04) —TimeQualitystruct andcompute_quality(refs)function. Metrics:total_refs,channel_count,refs_per_channel,max_rtc_gap_ns,min_rtc_gap_ns,ref_density_per_sec,drift_ppm_per_channel,rtc_span_ns.packet_standardmodule (P5-01) —PacketStandard::Ch10/Ch11enum for IRIG 106-17 chapter provenance.from_version(),is_ch10(),is_ch11(),Display.recording_eventmodule (GAP-08) —RecordingEventTypeenum (Started, Stopped, Overrun, IndexPoint, Reserved) andRecordingEventstruct withhas_reference_time()andmay_cause_time_gap(). Parses Data Type 0x02 event packets for time context.chrono_interopmodule (GAP-06) — Feature-gatedFrom<AbsoluteTime> for chrono::NaiveDateTimeand reverse. Enable withfeatures = ["chrono"].- F1 leap second handling (GAP-04) —
LeapSecondTable::offset_for_f1(year, doy)for Format 1 time sources (IRIG-B, GPS).is_near_leap_second(unix_seconds, window_secs)for flagging packets near leap second boundaries. - 34 new unit tests across 5 new test files:
packet_standard_tests.rs(5),streaming_tests.rs(10),quality_tests.rs(6),recording_event_tests.rs(9),chrono_interop.rs(4). - 7 new integration tests in
tests/pipeline.rs: PacketStandard from version, streaming correlator basic pipeline, streaming eviction, quality metrics, F1 leap second offset, near leap second boundary, recording event pipeline.
Changed
Cargo.toml— Version bumped to 0.6.0. Addedchronooptional dependency and feature gate.- CLI (irig106-time-cli) — Version bumped to 0.6.0.
- GitHub Actions CI — Added
--features serdeand--features chronoindividual test runs to catch cross-feature coupling. Pipeline now tests 4 feature combinations:--all-features,--no-default-features,--features serde,--features chrono. - Crate docs updated —
lib.rsfeature list now includes streaming correlation, quality metrics, packet standard, recording events, and chrono interop. - Re-exports —
PacketStandard,StreamingTimeCorrelator,StreamingRef,TimeQuality,compute_quality,RecordingEvent,RecordingEventTypeadded to crate root. - P5-05 (async API) permanently deferred — async runtime choice belongs to the application layer, not a
#![no_std]parsing library. - Rust formatting — Ran
cargo fmtacross all new modules. - Test matrix totals: 244 checks under default features (166 unit + 57 integration + 17 property + 4 doc) and 249 with
--all-features(170 unit + 57 integration + 17 property + 5 doc).
Fixed
RtcReset.indexnow reports global index — v0.5.0 regression wheredetect_rtc_resetsreturned per-channel indices instead of globalreferences()indices. Fixed viaglobal_index_of()helper that matches on all fields.TimeJump.indexcorrect for duplicate RTCs — v0.5.0 regression where.position()matched only onrtc + channel_id, always returning the first match for duplicate RTC values. Sameglobal_index_of()fix.- README/lib.rs serde claim — Now correctly says "except
TimeError" to match usage.md and CHANGELOG. - Clippy fixes — Removed unused
Rtcimport inquality.rs. Addedalloc::formatandalloc::vecimports inno_stdtest modules. Replaced manual abs diff withabs_diff()inis_near_leap_second. - chrono doc test — Replaced
ignorefence with real```rustdoc test that compiles under thechronofeature gate.
v0.5.0
[v0.5.0] - 2026-03-29
Added
- Channel-indexed correlation (P4-01) — Per-channel
BTreeMap<u16, Vec<ReferencePoint>>index alongside the flat RTC-sorted vec.nearest_for_channelis now O(log n) binary search instead of O(n) linear scan. Methods upgraded:correlate(…, Some(ch)),detect_time_jump,drift_ppm,detect_rtc_resets. - Per-channel accessors (P4-02) —
TimeCorrelator::channel_references(channel_id)returns a sorted slice for a single channel.channel_ids()returns all active channel IDs. - BCD lookup table (P4-03) —
extract_bcd_digitnow validates nibbles via a 16-entry constBCD_LUTinstead of a branch, eliminating conditional logic in the hot path. - Criterion benchmarks (P4-06) —
benches/correlation_bench.rswith statistical benchmarks forcorrelate_any,correlate_by_channel,detect_time_jump,drift_ppm, andadd_referenceat 10/100/1000/3600 reference point scales. serdefeature gate (GAP-02) — OptionalSerialize/Deserializederives on all public data types (exceptTimeErrorwhich contains&'static strfields). Enable withfeatures = ["serde"].- 7 new integration tests in
tests/pipeline.rs: channel_references accessor, channel_ids, channel-indexed correlate consistency, large-set correlate, sub_nanos year boundary crossing, same-day no-year-change, and no-year-info graceful wrap.
Changed
Cargo.toml— Version bumped to 0.5.0. Addedserdeoptional dependency and feature gate. Addedcriterionto dev-dependencies withcorrelation_benchbench target.- CLI (irig106-time-cli) — Version bumped to 0.5.0.
- Test structure — Extracted
version.rsinline tests tosrc/version_tests.rsto match the crate's test-per-module convention. - Crate docs updated —
lib.rsfeature list now includes channel-indexed O(log n) lookup and serde support. - Total test count: 203 (136 unit + 50 integration + 17 property).
Fixed
AbsoluteTime::sub_nanosyear rollover (GAP-05) — Subtracting past day 1 now correctly decrements the year (accounting for leap years) instead of wrapping to day 366. When no year info is available, assumes 365 days.
v0.4.0
[v0.4.0] - 2026-03-28
Added
versionmodule (P2-03) —Irig106Versionenum with variantsPre07throughV23plusUnknown(u8).detect_version(tmats_csdw)extracts the version from bits [7:0] of the TMATS CSDW. Helper methods:is_pre_ordering_guarantee(),supports_format_2(),has_gps_time_source().- Version-aware CSDW parsing (P2-04, P2-01) —
TimeF1Csdw::time_source_versioned(version)disambiguates time source value 3, which was "None" in 106-04 but "GPS" from 106-05 onward. Pre-07 files returnReserved(3)to signal ambiguity. - Configurable out-of-order window (P2-02) —
TimeCorrelator::with_ooo_window(ooo_window_ns)constructor. Pre-105 files may need unbounded OOO tolerance; post-105 defaults to 2 seconds viaDEFAULT_OOO_WINDOW_NS. Accessor:ooo_window_ns(). - RTC reset detection (GAP-07) —
TimeCorrelator::detect_rtc_resets(channel_id)identifies counter resets (as opposed to 48-bit wraps) by checking whether RTC went backward while absolute time continued forward. ReturnsVec<RtcReset>with before/after RTC and absolute time values. to_le_bytes()encoding (GAP-11) — Wire-format encoding for all parseable types, enabling packet construction foririg106-write:Rtc::to_le_bytes()→[u8; 6]TimeF1Csdw::to_le_bytes()→[u8; 4]TimeF2Csdw::to_le_bytes()→[u8; 4]NtpTime::to_le_bytes()→[u8; 8]PtpTime::to_le_bytes()→[u8; 10]DayFormatTime::to_le_bytes()→[u8; 8]DmyFormatTime::to_le_bytes()→[u8; 10]
- 19 new integration tests in
tests/pipeline.rs: version detection, version-aware CSDW, OOO window, RTC reset detection (basic, no false positive, channel isolation), andto_le_bytesround-trip for all 7 types. - 4 new property tests in
tests/properties.rs: encode round-trip for RTC, CSDW, NTP, and PTP.
Changed
- GitHub Actions — Updated
actions/checkoutfromv4tov6across the CI workflow. - Rust formatting — Ran
cargo fmtacross the repository to normalize code style. - Crate docs updated —
lib.rsfeature list now includes version detection, RTC reset detection, and encoding. - Re-exports —
RtcReset,detect_version, andIrig106Versionadded to crate root. Cargo.toml— Version bumped to 0.4.0.- CLI (irig106-time-cli) — Version bumped to 0.4.0.
- Total test count: 196 (136 unit + 43 integration + 17 property).
Fixed
detect_rtc_resetssorted by absolute time — References are stored sorted by RTC for lookup efficiency. After a reset, the low RTC value was inserted before pre-reset values, masking the discontinuity. Now sorts filtered channel references by absolute time to restore temporal order.- Removed unnecessary
as u16casts inDayFormatTime::to_le_bytes()andDmyFormatTime::to_le_bytes()— fields already typedu16(milliseconds,day_of_year,year) no longer carry redundant casts.
Known Issues
- Legacy support is specification-based only. Version-aware CSDW parsing and OOO tolerance are implemented per the IRIG 106-04/05 specifications and validated with synthetic tests, but have not been tested against real Ch10 files from legacy recorders (Ampex DCRsi, L-3 MARS, Acra KAM-500). Tracked as P1-07 and P2-05.
- Ch4 Binary Weighted Time bit layout is unverified against multi-vendor samples. The current decode assumes a single bit-field interpretation. Real-world validation against multiple recorder vendors is needed. Tracked as GAP-03.
v0.3.0
[v0.3.0] - 2026-03-28
Added
- GitHub Actions CI/CD (P1-03) — Test on stable + MSRV 1.87, clippy, rustfmt, rustdoc, and CLI build/lint.
impl Display for AbsoluteTime(GAP-01) — Formats asYYYY-MM-DD HH:MM:SS.mmm.uuuwhen year/month/day are available, orDay DDD HH:MM:SS.mmm.uuuotherwise.TimeCorrelator::drift_ppm(channel_id)(GAP-10) — Estimates RTC clock drift in parts-per-million against absolute time references. Returns average drift across consecutive same-channel reference pairs.- Calendar validation in DMY BCD decoding (GAP-09) —
DmyFormatTime::from_le_bytesnow rejects invalid day-for-month combinations (e.g., Feb 30, Jun 31) via adays_in_month()helper that accounts for leap years. - CLI
Protocolumn (P1-09/GAP-12) —channelscommand table now shows NTP/PTP protocol identity. Summary view appendsProto: NTPorProto: PTPfor Format 2 channels.TimeChannelInfocarries anetwork_protocolfield. proptestproperty-based tests (P1-08) —proptest = "1"added to[dev-dependencies].tests/properties.rsrewritten withproptest!macros covering RTC masking, round-trip, elapsed bounds, absolute time add/sub/monotonicity/Display, IEEE-1588 consistency, CSDW stability, NTP fraction bounds, and PTP monotonicity.- 10 new integration tests in
tests/pipeline.rs: Display formatting (DOY, DMY, zero-padding), drift_ppm (zero drift, fast RTC, channel isolation, insufficient refs), calendar validation, and year overflow guard.
Changed
#[deny(missing_docs)](P1-04) — Added to crate root. Allpub moddeclarations inlib.rsnow carry///doc comments.- Crate docs updated (GAP-13) —
lib.rsmodule-level documentation now includes network time (NTP/PTP) and drift estimation in the feature list. Requirement traceability paths updated to lowercase filenames. unix_seconds_to_ymd_pub(GAP-15) — Visibility reduced frompubtopub(crate).- Year overflow guard (GAP-16) —
unix_seconds_to_ymdnow usessaturating_addand breaks atu16::MAXto prevent panic on malformed timestamps far in the future. Cargo.toml— Version bumped to 0.3.0.rust-version = "1.87"MSRV declared.- CLI (irig106-time-cli) — Version bumped to 0.3.0.
- Total test count: 163 (126 unit + 24 integration + 13 property).
Fixed
- Escaped bit-range bracket notation (
[3:2],[3:0], etc.) in rustdoc comments acrossabsolute.rs,csdw.rs,secondary.rs,intra_packet.rs, andnetwork_time.rsto resolve 9 intra-doc link warnings. - Resolved
prop_assert!macro conflict with nestedformat!in property tests. - Removed unused imports and variables in
properties.rsandpipeline.rs.
v0.2.0
[v0.2.0] - 2026-03-28
Added
network_timemodule — Time Data Format 2 (0x12, Network Time) support, introduced in IRIG 106-17 (CR93).TimeF2Csdw— Format 2 channel-specific data word parser withNetworkTimeProtocolenum (NTP/PTP).NtpTime— NTP timestamp (32-bit seconds since 1900-01-01 UTC + 32-bit fractional seconds). Includesfraction_as_nanos()(2⁻³² → ns conversion),to_unix_seconds(),to_nanos_since_ntp_epoch(), andto_absolute().PtpTime— PTP/IEEE 1588 timestamp (48-bit seconds since 1970-01-01 TAI + 32-bit nanoseconds). Includesto_utc_seconds(tai_offset),to_nanos_since_tai_epoch(), andto_absolute(tai_offset).NetworkTimeenum — Discriminated union ofNtp(NtpTime)andPtp(PtpTime).parse_time_f2_payload()— Full payload dispatcher: CSDW → NTP or PTP time data.LeapSecondTable— Built-in table with all 28 TAI-UTC leap seconds from 1972-01-01 (offset 10) through 2017-01-01 (offset 37). Binary search lookup viaoffset_at_unix()andoffset_at_tai(). Runtime extensible viaadd().NTP_UNIX_EPOCH_OFFSETconstant (2,208,988,800 seconds).DEFAULT_TAI_UTC_OFFSETconstant (37 seconds, since 2017).
TimeCorrelator::add_reference_f2()— Accept Format 2 (NTP/PTP) time packets as correlation reference points, with automatic leap-second offset application for PTP sources.- 22 new unit tests in
network_time_tests.rscovering F2 CSDW parsing, NTP parse/convert/epoch math, PTP parse/TAI-UTC conversion, leap second table lookup, and full payload dispatch. - 5 new integration tests in
tests/pipeline.rs: full NTP pipeline, full PTP pipeline, mixed F1+F2 correlation, NTP sub-millisecond precision, and leap second table historical accuracy. - 2 new fuzz targets:
fuzz_ntpandfuzz_ptpcovering NTP and PTP parsing entry points. - 7 new benchmarks:
ntp_from_le_bytes(1.1 ns),ntp_to_absolute(115 ns),ptp_from_le_bytes(1.6 ns),ptp_to_absolute(119 ns),leap_table_lookup(6.6 ns),f2_ntp_payload_parse(2.7 ns). - L1 Requirements updated — 16 new L1 requirements for Format 2 (F2CSDW, NTP, PTP, F2COR, TAI) merged into
L1_Requirements.md, traced to Ch11 §11.2.3.3. Total: 53 L1 requirements. - L2/L3 Requirements updated — Format 2 functional decomposition and design specifications merged into
L2_Requirements.md(§3.10–3.14) andL3_Requirements.md(§3.12–3.13) with extended traceability matrices. - CLI (irig106-time-cli) —
ch10timenow recognizes and processes Type 0x12 Network Time packets in all commands (summary, channels, jumps, timeline, csv, correlate). Uses built-in leap second table for PTP→UTC conversion.
Changed
- Re-exports at crate root now include all Format 2 types:
TimeF2Csdw,NetworkTimeProtocol,NtpTime,PtpTime,NetworkTime,LeapSecondTable,LeapSecondEntry,NTP_UNIX_EPOCH_OFFSET,DEFAULT_TAI_UTC_OFFSET. - Total test count: 151 (126 unit + 15 integration + 10 property).
- Total fuzz targets: 10 (8 original + 2 new).
- Total benchmarks: 30 (23 original + 7 new).
- CLI
process_time_f2_packetrefactored to useadd_reference_f2()instead of manually duplicating NTP/PTP→AbsoluteTime conversion logic. - F2 L1 requirements merged from standalone addendum into canonical
L1_Requirements.md(§3.10–3.14). - F2 L2/L3 requirements merged from standalone addendum into canonical
L2_Requirements.md(§3.10–3.14) andL3_Requirements.md(§3.12–3.13). RemovedL2L3_REQUIREMENTS_F2_ADDENDUM.md. usage.mdupdated with 3 new Format 2 sections (§13 Processing Network Time Packets, §14 Working with the Leap Second Table, §15 Correlating with F1 + F2 Sources), updated imports and version references throughout.
Fixed
- Resolved clippy
manual_is_multiple_ofinnetwork_time.rsleap year check. - Resolved clippy
manual_range_containsinnetwork_time_tests.rsandpipeline.rsNTP fractional precision assertions. - Resolved clippy
unused_importsinpipeline.rsF2 integration tests. - Resolved clippy
unused_must_useintime_benchmarks.rsforntp_to_absoluteandptp_to_absolutebenchmarks. - Resolved clippy
needless_borrow,for_kv_map,redundant_closure,single_match, andmanual_is_multiple_ofin CLI.
Known Issues
- CLI
channelscommand displays NTP sources as "External / UTC" and PTP sources as "External / GPS" — the specific network protocol identity is not shown. Tracked as GAP-12, planned for v0.3.0 (P1-09).
v0.1.0
[v0.1.0] - 2026-03-26
Added
rtcmodule — 48-bit Relative Time Counter newtype (Rtc) withfrom_le_bytes,from_raw,elapsed_ticks,elapsed_nanos,to_nanos, and wrap-around safe arithmetic.absolutemodule —AbsoluteTimewith nanosecond precision, optional DMY calendar date,add_nanos/sub_nanoswith carry logic.Ch4BinaryTime(Chapter 4 Binary Weighted Time),Ieee1588Time, andErtc(64-bit Extended RTC).csdwmodule —TimeF1Csdwparser for Time Data Format 1 (0x11) channel-specific data word.TimeSource,TimeFormat, andDateFormatenums with bitfield extraction.bcdmodule —DayFormatTime(8-byte DOY BCD) andDmyFormatTime(10-byte DMY BCD) decoders with full BCD nibble validation, reserved-bit checking, and range validation.secondarymodule — Secondary header checksum validation (validate_secondary_checksum) and time parsing for Ch4, IEEE-1588, and ERTC formats viaparse_secondary_header.intra_packetmodule —IntraPacketTimeenum with 4 variants (Rtc, Ch4, Ieee1588, Ertc) andparse_intra_packet_timeformat dispatcher.correlationmodule —TimeCorrelatorwith sorted-insert reference points, nearest-point correlation with optional channel filtering, anddetect_time_jumpfor GPS lock discontinuity detection.errormodule —TimeErrornon-exhaustive enum with 6 variants:InvalidBcdDigit,ReservedBitSet,OutOfRange,ChecksumMismatch,NoReferencePoint,BufferTooShort.Displayimpl and feature-gatedstd::error::Error.#![no_std]support — Crate compiles with onlycoreandalloc. Optionalstdfeature forErrorimpl.- Zero required dependencies in
[dependencies]. - Zero
unsafeblocks in the entire crate. #[inline]annotations on all hot-path functions.- 104 unit tests across 8 modules (tests in separate files alongside source).
- 10 integration tests in
tests/pipeline.rscovering full CSDW-to-correlation flows, multi-channel scenarios, and GPS lock jump detection. - 10 property-based tests in
tests/properties.rs(10,000 iterations each, zero external dependencies). - 23 benchmarks in
benches/time_benchmarks.rs(zero-dependency,std::time::Instant). - 8 fuzz targets in
fuzz/fuzz_targets/covering all parsing entry points. - Companion CLI crate:
irig106-time-cliwith thech10timebinary for file summaries, channel inventory, jump detection, timelines, CSV export, and one-off RTC correlation. - Documentation: L1/L2/L3 requirements, architecture doc, security doc, usage guide, test index, project structure, roadmap, changelog, shared types migration plan, and rationale for separate repo.