lib

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

commit 8980ce18804175ea0442ec8b8e27485f96cf9fd7
parent 5c9b7fc8242415722aa1845a751dd45879715c2e
Author: triesap <tyson@radroots.org>
Date:   Fri, 26 Jun 2026 05:58:17 +0000

sdk: expose geonames runtime asset API

Diffstat:
Mcrates/sdk/Cargo.toml | 4++++
Acrates/sdk/src/geonames.rs | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/sdk/src/lib.rs | 19+++++++++++++++++++
Mcrates/sdk/tests/facade.rs | 8+++-----
Acrates/sdk/tests/geonames.rs | 48++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/trade_bindings/src/dto.rs | 7+++++--
Mcrates/trade_bindings/src/lib.rs | 6+++---
Mtools/sdk_xtask_import/src/dto_roots.rs | 6+++---
8 files changed, 174 insertions(+), 13 deletions(-)

diff --git a/crates/sdk/Cargo.toml b/crates/sdk/Cargo.toml @@ -58,8 +58,10 @@ runtime = [ "dep:hex", "dep:radroots_authority", "dep:radroots_event_store", + "dep:radroots_geocoder", "dep:radroots_outbox", "dep:radroots_relay_transport", + "dep:radroots_runtime_paths", "dep:sha2", "dep:sqlx", "dep:uuid", @@ -104,9 +106,11 @@ radroots_authority = { workspace = true, optional = true, default-features = fal radroots_event_store = { workspace = true, optional = true, default-features = false } radroots_events = { workspace = true, default-features = false } radroots_events_codec = { workspace = true, default-features = false } +radroots_geocoder = { workspace = true, optional = true } radroots_outbox = { workspace = true, optional = true, default-features = false } radroots_publish_proxy_protocol = { workspace = true, optional = true, default-features = false } radroots_relay_transport = { workspace = true, optional = true, default-features = false } +radroots_runtime_paths = { workspace = true, optional = true, default-features = false } radroots_trade = { workspace = true, default-features = false } radroots_identity = { workspace = true, optional = true, default-features = false } radroots_nostr = { workspace = true, optional = true, default-features = false } diff --git a/crates/sdk/src/geonames.rs b/crates/sdk/src/geonames.rs @@ -0,0 +1,89 @@ +#![cfg(feature = "runtime")] + +use std::path::{Path, PathBuf}; + +pub use radroots_geocoder::{ + GEONAMES_1_0_ASSET, GEONAMES_ASSET_BYTE_SIZE, GEONAMES_ASSET_FILE_NAME, GEONAMES_ASSET_HOST, + GEONAMES_ASSET_SHA256, GEONAMES_ASSET_URL, GEONAMES_ASSET_VERSION, GeoNamesAssetFetcher, + GeoNamesAssetSpec, GeoNamesAssetState, GeoNamesAssetStatus, GeoNamesBlockingHttpFetcher, + Geocoder, GeocoderCountryListResult, GeocoderError, GeocoderPoint, GeocoderReverseOptions, + GeocoderReverseResult, +}; +use radroots_geocoder::{ + ensure_default_geonames_asset_in_cache_root, ensure_geonames_asset_in_cache_root_with_fetcher, + inspect_default_geonames_asset_in_cache_root, inspect_geonames_asset_path, +}; +use radroots_runtime_paths::{ + default_shared_geonames_database_path_from_cache_root, + default_shared_geonames_root_from_cache_root, +}; + +pub fn radroots_sdk_geonames_database_path_from_cache_root( + cache_root: impl AsRef<Path>, +) -> PathBuf { + default_shared_geonames_database_path_from_cache_root(cache_root, GEONAMES_ASSET_VERSION) +} + +pub fn radroots_sdk_geonames_database_path_from_cache_root_for_version( + cache_root: impl AsRef<Path>, + version: &str, +) -> PathBuf { + default_shared_geonames_database_path_from_cache_root(cache_root, version) +} + +pub fn radroots_sdk_geonames_root_from_cache_root(cache_root: impl AsRef<Path>) -> PathBuf { + default_shared_geonames_root_from_cache_root(cache_root) +} + +pub fn radroots_sdk_inspect_geonames_database_in_cache_root( + cache_root: impl AsRef<Path>, +) -> Result<GeoNamesAssetStatus, GeocoderError> { + inspect_default_geonames_asset_in_cache_root(cache_root) +} + +pub fn radroots_sdk_inspect_geonames_database_path_with_spec( + path: impl AsRef<Path>, + spec: &GeoNamesAssetSpec, +) -> Result<GeoNamesAssetStatus, GeocoderError> { + inspect_geonames_asset_path(path, spec) +} + +pub fn radroots_sdk_ensure_geonames_database_in_cache_root( + cache_root: impl AsRef<Path>, +) -> Result<GeoNamesAssetStatus, GeocoderError> { + ensure_default_geonames_asset_in_cache_root(cache_root) +} + +pub fn radroots_sdk_ensure_geonames_database_in_cache_root_with_fetcher<F>( + cache_root: impl AsRef<Path>, + fetcher: &F, +) -> Result<GeoNamesAssetStatus, GeocoderError> +where + F: GeoNamesAssetFetcher, +{ + ensure_geonames_asset_in_cache_root_with_fetcher(cache_root, &GEONAMES_1_0_ASSET, fetcher) +} + +pub fn radroots_sdk_ensure_geonames_database_in_cache_root_with_spec_and_fetcher<F>( + cache_root: impl AsRef<Path>, + spec: &GeoNamesAssetSpec, + fetcher: &F, +) -> Result<GeoNamesAssetStatus, GeocoderError> +where + F: GeoNamesAssetFetcher, +{ + ensure_geonames_asset_in_cache_root_with_fetcher(cache_root, spec, fetcher) +} + +pub fn radroots_sdk_open_verified_geonames_database( + path: impl AsRef<Path>, +) -> Result<Geocoder, GeocoderError> { + Geocoder::open_verified_geonames_asset(path, &GEONAMES_1_0_ASSET) +} + +pub fn radroots_sdk_open_verified_geonames_database_with_spec( + path: impl AsRef<Path>, + spec: &GeoNamesAssetSpec, +) -> Result<Geocoder, GeocoderError> { + Geocoder::open_verified_geonames_asset(path, spec) +} diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs @@ -19,6 +19,8 @@ mod farm; #[cfg(feature = "runtime")] mod farms_runtime; #[cfg(feature = "runtime")] +mod geonames; +#[cfg(feature = "runtime")] mod idempotency; #[cfg(feature = "identity-models")] mod identity; @@ -54,6 +56,23 @@ pub use crate::farms_runtime::{ FarmPreparePublishRequest, FarmPublishPlan, }; #[cfg(feature = "runtime")] +pub use crate::geonames::{ + GEONAMES_1_0_ASSET, GEONAMES_ASSET_BYTE_SIZE, GEONAMES_ASSET_FILE_NAME, GEONAMES_ASSET_HOST, + GEONAMES_ASSET_SHA256, GEONAMES_ASSET_URL, GEONAMES_ASSET_VERSION, GeoNamesAssetFetcher, + GeoNamesAssetSpec, GeoNamesAssetState, GeoNamesAssetStatus, GeoNamesBlockingHttpFetcher, + Geocoder, GeocoderCountryListResult, GeocoderError, GeocoderPoint, GeocoderReverseOptions, + GeocoderReverseResult, radroots_sdk_ensure_geonames_database_in_cache_root, + radroots_sdk_ensure_geonames_database_in_cache_root_with_fetcher, + radroots_sdk_ensure_geonames_database_in_cache_root_with_spec_and_fetcher, + radroots_sdk_geonames_database_path_from_cache_root, + radroots_sdk_geonames_database_path_from_cache_root_for_version, + radroots_sdk_geonames_root_from_cache_root, + radroots_sdk_inspect_geonames_database_in_cache_root, + radroots_sdk_inspect_geonames_database_path_with_spec, + radroots_sdk_open_verified_geonames_database, + radroots_sdk_open_verified_geonames_database_with_spec, +}; +#[cfg(feature = "runtime")] pub use crate::idempotency::{SDK_IDEMPOTENCY_KEY_MAX_LEN, SdkIdempotencyKey}; #[cfg(feature = "runtime")] pub use crate::listings_runtime::{ diff --git a/crates/sdk/tests/facade.rs b/crates/sdk/tests/facade.rs @@ -10,7 +10,7 @@ use radroots_events::kinds::{ }; use radroots_events::listing::{ RadrootsListing, RadrootsListingAvailability, RadrootsListingBin, - RadrootsListingDeliveryMethod, RadrootsListingLocation, RadrootsListingProduct, + RadrootsListingDeliveryMethod, RadrootsListingProduct, RadrootsListingPublicLocation, RadrootsListingStatus, }; use radroots_events::order::{ @@ -103,14 +103,12 @@ fn sample_listing() -> RadrootsListing { status: RadrootsListingStatus::Active, }), delivery_method: Some(RadrootsListingDeliveryMethod::Pickup), - location: Some(RadrootsListingLocation { + location: Some(RadrootsListingPublicLocation { primary: "North Farm".into(), city: None, region: None, country: None, - lat: None, - lng: None, - geohash: None, + geohash: "9q8yy".into(), }), images: None, } diff --git a/crates/sdk/tests/geonames.rs b/crates/sdk/tests/geonames.rs @@ -0,0 +1,48 @@ +#![cfg(feature = "runtime")] + +use radroots_sdk::{ + GEONAMES_ASSET_HOST, GEONAMES_ASSET_VERSION, GeoNamesAssetState, + radroots_sdk_geonames_database_path_from_cache_root, + radroots_sdk_geonames_database_path_from_cache_root_for_version, + radroots_sdk_geonames_root_from_cache_root, + radroots_sdk_inspect_geonames_database_in_cache_root, +}; + +#[test] +fn sdk_geonames_facade_resolves_shared_cache_paths_and_reports_missing_state() { + let tempdir = tempfile::tempdir().expect("tempdir"); + let cache_root = tempdir.path().join("cache"); + + assert_eq!(GEONAMES_ASSET_HOST, "assets.radroots.io"); + assert_eq!(GEONAMES_ASSET_VERSION, "1.0"); + assert_eq!( + radroots_sdk_geonames_root_from_cache_root(&cache_root), + cache_root.join("shared").join("geonames") + ); + assert_eq!( + radroots_sdk_geonames_database_path_from_cache_root(&cache_root), + cache_root + .join("shared") + .join("geonames") + .join("geonames-1.0.db") + ); + assert_eq!( + radroots_sdk_geonames_database_path_from_cache_root_for_version(&cache_root, "1.1"), + cache_root + .join("shared") + .join("geonames") + .join("geonames-1.1.db") + ); + + let status = + radroots_sdk_inspect_geonames_database_in_cache_root(&cache_root).expect("inspection"); + assert_eq!(status.state, GeoNamesAssetState::Missing); + assert_eq!(status.version, "1.0"); + assert_eq!( + status.path, + cache_root + .join("shared") + .join("geonames") + .join("geonames-1.0.db") + ); +} diff --git a/crates/trade_bindings/src/dto.rs b/crates/trade_bindings/src/dto.rs @@ -74,7 +74,10 @@ imported_ts_type!( "RadrootsListingDeliveryMethod" ); imported_ts_type!(RadrootsListingImageImport, "RadrootsListingImage"); -imported_ts_type!(RadrootsListingLocationImport, "RadrootsListingLocation"); +imported_ts_type!( + RadrootsListingPublicLocationImport, + "RadrootsListingPublicLocation" +); imported_ts_type!(RadrootsListingProductImport, "RadrootsListingProduct"); imported_ts_type!(RadrootsNostrEventPtrImport, "RadrootsNostrEventPtr"); imported_ts_type!(RadrootsPlotRefImport, "RadrootsPlotRef"); @@ -207,7 +210,7 @@ pub struct RadrootsTradeListingProjection { pub inventory_available: Option<RadrootsCoreDecimalImport>, pub availability: Option<RadrootsListingAvailabilityImport>, pub delivery_method: Option<RadrootsListingDeliveryMethodImport>, - pub location: Option<RadrootsListingLocationImport>, + pub location: Option<RadrootsListingPublicLocationImport>, pub images: Option<Vec<RadrootsListingImageImport>>, pub order_count: u32, pub open_order_count: u32, diff --git a/crates/trade_bindings/src/lib.rs b/crates/trade_bindings/src/lib.rs @@ -35,8 +35,8 @@ pub const TRADE_TYPE_INVENTORY: &[TradeTypeInventoryEntry] = &[ event_import("RadrootsListingAvailability"), event_import("RadrootsListingBin"), event_import("RadrootsListingDeliveryMethod"), - event_import("RadrootsListingLocation"), event_import("RadrootsListingProduct"), + event_import("RadrootsListingPublicLocation"), event_import("RadrootsListingStatus"), local_shape("RadrootsTradeFacetCount"), source_root("RadrootsTradeListing"), @@ -181,8 +181,8 @@ mod tests { "RadrootsListingAvailability", "RadrootsListingBin", "RadrootsListingDeliveryMethod", - "RadrootsListingLocation", "RadrootsListingProduct", + "RadrootsListingPublicLocation", "RadrootsListingStatus", "RadrootsTradeFacetCount", "RadrootsTradeListing", @@ -230,8 +230,8 @@ mod tests { "RadrootsListingAvailability", "RadrootsListingBin", "RadrootsListingDeliveryMethod", - "RadrootsListingLocation", "RadrootsListingProduct", + "RadrootsListingPublicLocation", "RadrootsListingStatus", "RadrootsTradeMessageType", "RadrootsTradeOrderStatus", diff --git a/tools/sdk_xtask_import/src/dto_roots.rs b/tools/sdk_xtask_import/src/dto_roots.rs @@ -262,8 +262,8 @@ fn trade_import_options(mut options: DtoRegistryRenderOptions) -> DtoRegistryRen "RadrootsListingBin", "RadrootsListingDeliveryMethod", "RadrootsListingImage", - "RadrootsListingLocation", "RadrootsListingProduct", + "RadrootsListingPublicLocation", "RadrootsListingStatus", "RadrootsNostrEventPtr", "RadrootsPlotRef", @@ -380,7 +380,7 @@ mod tests { "RadrootsDocument", "RadrootsDocumentSubject", "RadrootsFarm", - "RadrootsFarmLocation", + "RadrootsFarmPublicLocation", "RadrootsFarmRef", "RadrootsFollow", "RadrootsFollowProfile", @@ -404,9 +404,9 @@ mod tests { "RadrootsListingDeliveryMethod", "RadrootsListingImage", "RadrootsListingImageSize", - "RadrootsListingLocation", "RadrootsListingProduct", "RadrootsListingProductTagKeys", + "RadrootsListingPublicLocation", "RadrootsListingStatus", "RadrootsMessage", "RadrootsMessageFile",