lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

commit 09ca67d3d7fa8bb29f7b0b04c3e6da935ea5f348
parent bd57d87d94afbceaf6567da55de5f2ab58bb4563
Author: triesap <tyson@radroots.org>
Date:   Fri, 12 Jun 2026 04:12:59 -0700

release: close social preflight gaps

- preserve listing published_at tags in the trade parser
- cover the trade parser published_at round trip and invalid numeric tag path
- run events_codec coverage with the serde_json codec test surface
- record the temporary events_codec branch coverage override for heavy development

Diffstat:
Mcrates/trade/src/listing/codec.rs | 50+++++++++++++++++++++++++++++++++++++++++++++++++-
Mpolicy/coverage/policy.toml | 8++++++++
Mpolicy/coverage/profiles.toml | 5+++++
3 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/crates/trade/src/listing/codec.rs b/crates/trade/src/listing/codec.rs @@ -16,7 +16,7 @@ use radroots_events::listing::{ }; use radroots_events::plot::RadrootsPlotRef; use radroots_events::resource_area::RadrootsResourceAreaRef; -use radroots_events::tags::TAG_D; +use radroots_events::tags::{TAG_D, TAG_PUBLISHED_AT}; pub(crate) use radroots_events::trade::RadrootsTradeListingParseError as TradeListingParseError; use radroots_events_codec::d_tag::is_d_tag_base64url; use radroots_events_codec::error::EventEncodeError; @@ -56,6 +56,13 @@ fn parse_unit(s: &str) -> Result<RadrootsCoreUnit, TradeListingParseError> { .map_err(|_| TradeListingParseError::InvalidUnit) } +fn parse_u64_tag_value(value: Option<&String>, field: &str) -> Result<u64, TradeListingParseError> { + value + .ok_or_else(|| TradeListingParseError::InvalidTag(field.to_string()))? + .parse::<u64>() + .map_err(|_| TradeListingParseError::InvalidNumber(field.to_string())) +} + fn parse_d_tag(tags: &[Vec<String>]) -> Result<String, TradeListingParseError> { let tag = tags .iter() @@ -193,6 +200,7 @@ fn listing_from_tags( let mut delivery_method: Option<RadrootsListingDeliveryMethod> = None; let mut images: Vec<RadrootsListingImage> = Vec::new(); let mut geohash: Option<String> = None; + let mut published_at: Option<u64> = None; let has_structured_location = tags .iter() @@ -208,6 +216,9 @@ fn listing_from_tags( "title" => set_if_empty(&mut product.title, tag.get(1)), "category" => set_if_empty(&mut product.category, tag.get(1)), "summary" => set_optional(&mut product.summary, tag.get(1)), + TAG_PUBLISHED_AT => { + published_at = Some(parse_u64_tag_value(tag.get(1), TAG_PUBLISHED_AT)?); + } "process" => set_optional(&mut product.process, tag.get(1)), "lot" => set_optional(&mut product.lot, tag.get(1)), "location" => { @@ -462,6 +473,7 @@ fn listing_from_tags( Ok(RadrootsListing { d_tag, + published_at, farm: farm_ref, product, primary_bin_id, @@ -738,6 +750,42 @@ mod tests { } #[test] + fn listing_from_tags_roundtrips_published_at_tag() { + let mut tags = base_trade_tags(); + tags.push(vec![TAG_PUBLISHED_AT.into(), "1781895600".into()]); + + let listing = listing_from_tags( + &tags, + listing_d_tag(), + farm_ref(), + "seller".to_string(), + None, + None, + ) + .expect("listing"); + + assert_eq!(listing.published_at, Some(1_781_895_600)); + + let published_at = tags + .iter_mut() + .find(|tag| tag.first().map(|value| value.as_str()) == Some(TAG_PUBLISHED_AT)) + .expect("published_at tag"); + published_at[1] = "bad".to_string(); + + let err = listing_from_tags( + &tags, + listing_d_tag(), + farm_ref(), + "seller".to_string(), + None, + None, + ) + .unwrap_err(); + + assert_eq!(parse_error_tag(err), TAG_PUBLISHED_AT.to_string()); + } + + #[test] fn listing_from_tags_rejects_invalid_d_tag() { let tags = base_trade_tags(); diff --git a/policy/coverage/policy.toml b/policy/coverage/policy.toml @@ -26,6 +26,14 @@ fail_under_branches = 73.638 temporary = true reason = "heavy-development branch coverage gap for publish 0.1.0-alpha.2" +[overrides.radroots_events_codec] +fail_under_exec_lines = 90.0 +fail_under_functions = 90.0 +fail_under_regions = 90.0 +fail_under_branches = 81.264 +temporary = true +reason = "heavy-development branch coverage gap for publish 0.1.0-alpha.2" + [overrides.radroots_nostr_signer] fail_under_exec_lines = 89.185 fail_under_functions = 90.0 diff --git a/policy/coverage/profiles.toml b/policy/coverage/profiles.toml @@ -8,6 +8,11 @@ no_default_features = true features = [] test_threads = 1 +[profiles.crates."radroots_events_codec"] +no_default_features = false +features = ["serde_json"] +test_threads = 1 + [profiles.crates."radroots_nostr_runtime"] no_default_features = true features = ["std"]