lib

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

commit 8e0bba5e9d6be2917593433d70c090e5299324ee
parent f60e1eee7d544af9035a646a215935a65d056fa2
Author: triesap <tyson@radroots.org>
Date:   Sun, 15 Feb 2026 17:51:05 +0000

tangle-events: apply cargo fmt

Diffstat:
Mtangle-events/src/canonical.rs | 9+++++----
Mtangle-events/src/emit.rs | 285+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Mtangle-events/src/event_state.rs | 10+++++++---
Mtangle-events/src/geo.rs | 4++--
Mtangle-events/src/ingest.rs | 182+++++++++++++++++++++++++++++++++++++------------------------------------------
Mtangle-events/src/lib.rs | 31+++++++++++--------------------
Mtangle-events/src/sync_state.rs | 8+++++---
Mtangle-events/src/tests.rs | 39++++++++++++++++++---------------------
8 files changed, 291 insertions(+), 277 deletions(-)

diff --git a/tangle-events/src/canonical.rs b/tangle-events/src/canonical.rs @@ -1,14 +1,15 @@ #[cfg(not(feature = "std"))] -use alloc::{string::{String, ToString}, vec::Vec}; +use alloc::{ + string::{String, ToString}, + vec::Vec, +}; use serde::Serialize; use serde_json::{Map, Value}; use crate::error::RadrootsTangleEventsError; -pub fn canonical_json_string<T: Serialize>( - value: &T, -) -> Result<String, RadrootsTangleEventsError> { +pub fn canonical_json_string<T: Serialize>(value: &T) -> Result<String, RadrootsTangleEventsError> { let value = serde_json::to_value(value).map_err(|_| { RadrootsTangleEventsError::InvalidData("canonical json serialization failed".to_string()) })?; diff --git a/tangle-events/src/emit.rs b/tangle-events/src/emit.rs @@ -1,26 +1,23 @@ #[cfg(not(feature = "std"))] use alloc::format; #[cfg(not(feature = "std"))] -use alloc::{collections::BTreeMap, string::{String, ToString}, vec::Vec}; +use alloc::{ + collections::BTreeMap, + string::{String, ToString}, + vec::Vec, +}; #[cfg(feature = "std")] use std::collections::BTreeMap; use radroots_events::farm::{ - RadrootsFarm, - RadrootsFarmLocation, - RadrootsFarmRef, - RadrootsGcsLocation, - RadrootsGeoJsonPoint, + RadrootsFarm, RadrootsFarmLocation, RadrootsFarmRef, RadrootsGcsLocation, RadrootsGeoJsonPoint, RadrootsGeoJsonPolygon, }; use radroots_events::kinds::{KIND_FARM, KIND_LIST_SET_GENERIC, KIND_PLOT}; use radroots_events::plot::RadrootsPlot; use radroots_events::profile::{ - radroots_profile_type_from_tag_value, - radroots_profile_type_tag_value, - RadrootsProfile, - RadrootsProfileType, - RADROOTS_PROFILE_TYPE_TAG_KEY, + RADROOTS_PROFILE_TYPE_TAG_KEY, RadrootsProfile, RadrootsProfileType, + radroots_profile_type_from_tag_value, radroots_profile_type_tag_value, }; use radroots_events_codec::farm::encode as farm_encode; use radroots_events_codec::farm::list_sets as farm_list_sets; @@ -28,71 +25,42 @@ use radroots_events_codec::list_set::encode as list_set_encode; use radroots_events_codec::plot::encode as plot_encode; use radroots_events_codec::wire::WireEventParts; use radroots_sql_core::SqlExecutor; +use radroots_tangle_db::{ + farm, farm_gcs_location, farm_member, farm_member_claim, farm_tag, gcs_location, nostr_profile, + plot, plot_gcs_location, plot_tag, +}; use radroots_tangle_db_schema::farm::{ - Farm, - IFarmFindMany, - IFarmFindOne, - IFarmFindOneArgs, - IFarmFieldsFilter, + Farm, IFarmFieldsFilter, IFarmFindMany, IFarmFindOne, IFarmFindOneArgs, }; use radroots_tangle_db_schema::farm_gcs_location::{ - FarmGcsLocation, - IFarmGcsLocationFindMany, - IFarmGcsLocationFieldsFilter, + FarmGcsLocation, IFarmGcsLocationFieldsFilter, IFarmGcsLocationFindMany, }; use radroots_tangle_db_schema::farm_member::{ - FarmMember, - IFarmMemberFindMany, - IFarmMemberFieldsFilter, + FarmMember, IFarmMemberFieldsFilter, IFarmMemberFindMany, }; use radroots_tangle_db_schema::farm_member_claim::{ - FarmMemberClaim, - IFarmMemberClaimFindMany, - IFarmMemberClaimFieldsFilter, + FarmMemberClaim, IFarmMemberClaimFieldsFilter, IFarmMemberClaimFindMany, }; -use radroots_tangle_db_schema::farm_tag::{IFarmTagFindMany, IFarmTagFieldsFilter}; +use radroots_tangle_db_schema::farm_tag::{IFarmTagFieldsFilter, IFarmTagFindMany}; use radroots_tangle_db_schema::gcs_location::{ - GcsLocation, - IGcsLocationFindOne, - IGcsLocationFindOneArgs, - GcsLocationQueryBindValues, + GcsLocation, GcsLocationQueryBindValues, IGcsLocationFindOne, IGcsLocationFindOneArgs, }; use radroots_tangle_db_schema::nostr_profile::{ - INostrProfileFindOne, - INostrProfileFindOneArgs, - NostrProfileQueryBindValues, + INostrProfileFindOne, INostrProfileFindOneArgs, NostrProfileQueryBindValues, }; -use radroots_tangle_db_schema::plot::{Plot, IPlotFindMany, IPlotFieldsFilter}; +use radroots_tangle_db_schema::plot::{IPlotFieldsFilter, IPlotFindMany, Plot}; use radroots_tangle_db_schema::plot_gcs_location::{ - PlotGcsLocation, - IPlotGcsLocationFindMany, - IPlotGcsLocationFieldsFilter, -}; -use radroots_tangle_db_schema::plot_tag::{IPlotTagFindMany, IPlotTagFieldsFilter}; -use radroots_tangle_db::{ - farm, - farm_gcs_location, - farm_member, - farm_member_claim, - farm_tag, - gcs_location, - nostr_profile, - plot, - plot_gcs_location, - plot_tag, + IPlotGcsLocationFieldsFilter, IPlotGcsLocationFindMany, PlotGcsLocation, }; +use radroots_tangle_db_schema::plot_tag::{IPlotTagFieldsFilter, IPlotTagFindMany}; use serde_json::Value; -use crate::error::RadrootsTangleEventsError; use crate::canonical::canonical_json_string; +use crate::error::RadrootsTangleEventsError; use crate::geo::{geojson_point_from_lat_lng, geojson_polygon_circle_wgs84}; use crate::types::{ - RADROOTS_TANGLE_TRANSFER_VERSION, - RadrootsTangleEventDraft, - RadrootsTangleFarmSelector, - RadrootsTangleSyncBundle, - RadrootsTangleSyncOptions, - RadrootsTangleSyncRequest, + RADROOTS_TANGLE_TRANSFER_VERSION, RadrootsTangleEventDraft, RadrootsTangleFarmSelector, + RadrootsTangleSyncBundle, RadrootsTangleSyncOptions, RadrootsTangleSyncRequest, }; const ROLE_PRIMARY: &str = "primary"; @@ -113,9 +81,7 @@ pub fn radroots_tangle_sync_all_with_options<E: SqlExecutor>( options: Option<&RadrootsTangleSyncOptions>, ) -> Result<RadrootsTangleSyncBundle, RadrootsTangleEventsError> { let farm = resolve_farm(exec, farm_selector)?; - let include_profiles = options - .and_then(|opt| opt.include_profiles) - .unwrap_or(true); + let include_profiles = options.and_then(|opt| opt.include_profiles).unwrap_or(true); let include_list_sets = options .and_then(|opt| opt.include_list_sets) .unwrap_or(true); @@ -233,25 +199,15 @@ pub fn radroots_tangle_list_set_events<E: SqlExecutor>( let members = load_farm_members(exec, &farm.id)?; let plots = load_plots(exec, &farm.id)?; - let members_list = farm_list_sets::farm_members_list_set( - &farm.d_tag, - role_pubkeys(&members, ROLE_MEMBER), - )?; - let owners_list = farm_list_sets::farm_owners_list_set( - &farm.d_tag, - role_pubkeys(&members, ROLE_OWNER), - )?; - let workers_list = farm_list_sets::farm_workers_list_set( - &farm.d_tag, - role_pubkeys(&members, ROLE_WORKER), - )?; + let members_list = + farm_list_sets::farm_members_list_set(&farm.d_tag, role_pubkeys(&members, ROLE_MEMBER))?; + let owners_list = + farm_list_sets::farm_owners_list_set(&farm.d_tag, role_pubkeys(&members, ROLE_OWNER))?; + let workers_list = + farm_list_sets::farm_workers_list_set(&farm.d_tag, role_pubkeys(&members, ROLE_WORKER))?; let plot_ids = sorted_plot_ids(&plots); - let plots_list = farm_list_sets::farm_plots_list_set( - &farm.d_tag, - &farm.pubkey, - plot_ids, - )?; + let plots_list = farm_list_sets::farm_plots_list_set(&farm.d_tag, &farm.pubkey, plot_ids)?; let list_sets = [members_list, owners_list, workers_list, plots_list]; let mut events = Vec::new(); @@ -303,20 +259,28 @@ fn resolve_farm<E: SqlExecutor>( on: radroots_tangle_db_schema::farm::FarmQueryBindValues::Id { id: id.clone() }, }), )?; - return result - .result - .ok_or_else(|| RadrootsTangleEventsError::InvalidSelector(format!("farm not found: {id}"))); + return result.result.ok_or_else(|| { + RadrootsTangleEventsError::InvalidSelector(format!("farm not found: {id}")) + }); } - let d_tag = selector.d_tag.as_ref().map(|v| v.trim()).filter(|v| !v.is_empty()); - let pubkey = selector.pubkey.as_ref().map(|v| v.trim()).filter(|v| !v.is_empty()); + let d_tag = selector + .d_tag + .as_ref() + .map(|v| v.trim()) + .filter(|v| !v.is_empty()); + let pubkey = selector + .pubkey + .as_ref() + .map(|v| v.trim()) + .filter(|v| !v.is_empty()); let (d_tag, pubkey) = match (d_tag, pubkey) { (Some(d_tag), Some(pubkey)) => (d_tag, pubkey), _ => { return Err(RadrootsTangleEventsError::InvalidSelector( "farm selector requires id or (d_tag + pubkey)".to_string(), - )) + )); } }; @@ -336,7 +300,12 @@ fn resolve_farm<E: SqlExecutor>( location_region: None, location_country: None, }; - let result = farm::find_many(exec, &IFarmFindMany { filter: Some(filter) })?; + let result = farm::find_many( + exec, + &IFarmFindMany { + filter: Some(filter), + }, + )?; if result.results.len() == 1 { return Ok(result.results.into_iter().next().expect("farm result")); } @@ -356,8 +325,17 @@ fn collect_farm_tags<E: SqlExecutor>( farm_id: Some(farm_id.to_string()), tag: None, }; - let result = farm_tag::find_many(exec, &IFarmTagFindMany { filter: Some(filter) })?; - let mut tags = result.results.into_iter().map(|row| row.tag).collect::<Vec<_>>(); + let result = farm_tag::find_many( + exec, + &IFarmTagFindMany { + filter: Some(filter), + }, + )?; + let mut tags = result + .results + .into_iter() + .map(|row| row.tag) + .collect::<Vec<_>>(); tags.sort(); tags.dedup(); Ok(tags) @@ -374,8 +352,17 @@ fn collect_plot_tags<E: SqlExecutor>( plot_id: Some(plot_id.to_string()), tag: None, }; - let result = plot_tag::find_many(exec, &IPlotTagFindMany { filter: Some(filter) })?; - let mut tags = result.results.into_iter().map(|row| row.tag).collect::<Vec<_>>(); + let result = plot_tag::find_many( + exec, + &IPlotTagFindMany { + filter: Some(filter), + }, + )?; + let mut tags = result + .results + .into_iter() + .map(|row| row.tag) + .collect::<Vec<_>>(); tags.sort(); tags.dedup(); Ok(tags) @@ -393,7 +380,12 @@ fn load_farm_members<E: SqlExecutor>( member_pubkey: None, role: None, }; - let result = farm_member::find_many(exec, &IFarmMemberFindMany { filter: Some(filter) })?; + let result = farm_member::find_many( + exec, + &IFarmMemberFindMany { + filter: Some(filter), + }, + )?; Ok(result.results) } @@ -409,13 +401,19 @@ fn role_pubkeys(members: &[FarmMember], role: &str) -> Vec<String> { } fn sorted_plot_ids(plots: &[Plot]) -> Vec<String> { - let mut ids = plots.iter().map(|plot| plot.d_tag.clone()).collect::<Vec<_>>(); + let mut ids = plots + .iter() + .map(|plot| plot.d_tag.clone()) + .collect::<Vec<_>>(); ids.sort(); ids.dedup(); ids } -fn load_plots<E: SqlExecutor>(exec: &E, farm_id: &str) -> Result<Vec<Plot>, RadrootsTangleEventsError> { +fn load_plots<E: SqlExecutor>( + exec: &E, + farm_id: &str, +) -> Result<Vec<Plot>, RadrootsTangleEventsError> { let filter = IPlotFieldsFilter { id: None, created_at: None, @@ -429,7 +427,12 @@ fn load_plots<E: SqlExecutor>(exec: &E, farm_id: &str) -> Result<Vec<Plot>, Radr location_region: None, location_country: None, }; - let result = plot::find_many(exec, &IPlotFindMany { filter: Some(filter) })?; + let result = plot::find_many( + exec, + &IPlotFindMany { + filter: Some(filter), + }, + )?; let mut plots = result.results; plots.sort_by(|a, b| a.d_tag.cmp(&b.d_tag)); Ok(plots) @@ -454,25 +457,22 @@ fn load_plot_location<E: SqlExecutor>( plot: &Plot, ) -> Result<Option<radroots_events::plot::RadrootsPlotLocation>, RadrootsTangleEventsError> { let location = load_gcs_location_for_plot(exec, &plot.id)?; - Ok(location.map(|gcs| radroots_events::plot::RadrootsPlotLocation { - primary: plot.location_primary.clone(), - city: plot.location_city.clone(), - region: plot.location_region.clone(), - country: plot.location_country.clone(), - gcs, - })) + Ok( + location.map(|gcs| radroots_events::plot::RadrootsPlotLocation { + primary: plot.location_primary.clone(), + city: plot.location_city.clone(), + region: plot.location_region.clone(), + country: plot.location_country.clone(), + gcs, + }), + ) } fn load_gcs_location_for_farm<E: SqlExecutor>( exec: &E, farm_id: &str, ) -> Result<Option<RadrootsGcsLocation>, RadrootsTangleEventsError> { - let primary = load_relation_by_role( - exec, - farm_id, - ROLE_PRIMARY, - RelationType::Farm, - )?; + let primary = load_relation_by_role(exec, farm_id, ROLE_PRIMARY, RelationType::Farm)?; match primary { Some(gcs) => Ok(Some(gcs)), None => load_relation_by_role(exec, farm_id, "", RelationType::Farm), @@ -483,12 +483,7 @@ fn load_gcs_location_for_plot<E: SqlExecutor>( exec: &E, plot_id: &str, ) -> Result<Option<RadrootsGcsLocation>, RadrootsTangleEventsError> { - let primary = load_relation_by_role( - exec, - plot_id, - ROLE_PRIMARY, - RelationType::Plot, - )?; + let primary = load_relation_by_role(exec, plot_id, ROLE_PRIMARY, RelationType::Plot)?; match primary { Some(gcs) => Ok(Some(gcs)), None => load_relation_by_role(exec, plot_id, "", RelationType::Plot), @@ -514,13 +509,23 @@ fn load_relation_by_role<E: SqlExecutor>( updated_at: None, farm_id: Some(id.to_string()), gcs_location_id: None, - role: if role.is_empty() { None } else { Some(role.to_string()) }, + role: if role.is_empty() { + None + } else { + Some(role.to_string()) + }, }; let result = farm_gcs_location::find_many( exec, - &IFarmGcsLocationFindMany { filter: Some(filter) }, + &IFarmGcsLocationFindMany { + filter: Some(filter), + }, )?; - result.results.into_iter().map(RelationRow::Farm).collect::<Vec<_>>() + result + .results + .into_iter() + .map(RelationRow::Farm) + .collect::<Vec<_>>() } RelationType::Plot => { let filter = IPlotGcsLocationFieldsFilter { @@ -529,13 +534,23 @@ fn load_relation_by_role<E: SqlExecutor>( updated_at: None, plot_id: Some(id.to_string()), gcs_location_id: None, - role: if role.is_empty() { None } else { Some(role.to_string()) }, + role: if role.is_empty() { + None + } else { + Some(role.to_string()) + }, }; let result = plot_gcs_location::find_many( exec, - &IPlotGcsLocationFindMany { filter: Some(filter) }, + &IPlotGcsLocationFindMany { + filter: Some(filter), + }, )?; - result.results.into_iter().map(RelationRow::Plot).collect::<Vec<_>>() + result + .results + .into_iter() + .map(RelationRow::Plot) + .collect::<Vec<_>>() } }; @@ -581,14 +596,12 @@ impl RelationRow { } fn location_role_rank(role: &str) -> u8 { - if role == ROLE_PRIMARY { - 0 - } else { - 1 - } + if role == ROLE_PRIMARY { 0 } else { 1 } } -fn gcs_location_to_event(gcs: &GcsLocation) -> Result<RadrootsGcsLocation, RadrootsTangleEventsError> { +fn gcs_location_to_event( + gcs: &GcsLocation, +) -> Result<RadrootsGcsLocation, RadrootsTangleEventsError> { let point = parse_point(&gcs.point, gcs.lat, gcs.lng); let polygon = parse_polygon(&gcs.polygon, gcs.lat, gcs.lng); Ok(RadrootsGcsLocation { @@ -637,7 +650,8 @@ fn parse_polygon(value: &str, lat: f64, lng: f64) -> RadrootsGeoJsonPolygon { fn load_profile<E: SqlExecutor>( exec: &E, pubkey: &str, -) -> Result<Option<radroots_tangle_db_schema::nostr_profile::NostrProfile>, RadrootsTangleEventsError> { +) -> Result<Option<radroots_tangle_db_schema::nostr_profile::NostrProfile>, RadrootsTangleEventsError> +{ let result = nostr_profile::find_one( exec, &INostrProfileFindOne::On(INostrProfileFindOneArgs { @@ -688,7 +702,9 @@ fn profile_event( }) } -fn serialize_profile_content(profile: &RadrootsProfile) -> Result<String, RadrootsTangleEventsError> { +fn serialize_profile_content( + profile: &RadrootsProfile, +) -> Result<String, RadrootsTangleEventsError> { let mut obj = serde_json::Map::new(); obj.insert("name".to_string(), Value::from(profile.name.clone())); if let Some(value) = profile.display_name.as_ref() { @@ -723,7 +739,10 @@ fn collect_member_pubkeys<E: SqlExecutor>( farm_id: &str, ) -> Result<Vec<String>, RadrootsTangleEventsError> { let members = load_farm_members(exec, farm_id)?; - let mut pubkeys = members.into_iter().map(|row| row.member_pubkey).collect::<Vec<_>>(); + let mut pubkeys = members + .into_iter() + .map(|row| row.member_pubkey) + .collect::<Vec<_>>(); pubkeys.sort(); pubkeys.dedup(); Ok(pubkeys) @@ -751,7 +770,12 @@ fn load_member_claims<E: SqlExecutor>( member_pubkey: None, farm_pubkey: Some(farm_pubkey.to_string()), }; - let result = farm_member_claim::find_many(exec, &IFarmMemberClaimFindMany { filter: Some(filter) })?; + let result = farm_member_claim::find_many( + exec, + &IFarmMemberClaimFindMany { + filter: Some(filter), + }, + )?; Ok(result.results) } @@ -766,7 +790,12 @@ fn load_member_claims_for_member<E: SqlExecutor>( member_pubkey: Some(member_pubkey.to_string()), farm_pubkey: None, }; - let result = farm_member_claim::find_many(exec, &IFarmMemberClaimFindMany { filter: Some(filter) })?; + let result = farm_member_claim::find_many( + exec, + &IFarmMemberClaimFindMany { + filter: Some(filter), + }, + )?; Ok(result.results) } diff --git a/tangle-events/src/event_state.rs b/tangle-events/src/event_state.rs @@ -1,7 +1,10 @@ #[cfg(not(feature = "std"))] use alloc::format; #[cfg(not(feature = "std"))] -use alloc::{string::{String, ToString}, vec::Vec}; +use alloc::{ + string::{String, ToString}, + vec::Vec, +}; #[cfg(feature = "std")] use std::{string::String, vec::Vec}; @@ -17,8 +20,9 @@ pub fn event_content_hash( content: &str, tags: &[Vec<String>], ) -> Result<String, RadrootsTangleEventsError> { - let tags_json = serde_json::to_string(tags) - .map_err(|_| RadrootsTangleEventsError::InvalidData("tags serialization failed".to_string()))?; + let tags_json = serde_json::to_string(tags).map_err(|_| { + RadrootsTangleEventsError::InvalidData("tags serialization failed".to_string()) + })?; let mut hasher = Sha256::new(); hasher.update(content.as_bytes()); hasher.update(tags_json.as_bytes()); diff --git a/tangle-events/src/geo.rs b/tangle-events/src/geo.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "std"))] -use alloc::{string::String, vec::Vec}; -#[cfg(not(feature = "std"))] use alloc::vec; +#[cfg(not(feature = "std"))] +use alloc::{string::String, vec::Vec}; use radroots_events::farm::{RadrootsGeoJsonPoint, RadrootsGeoJsonPolygon}; diff --git a/tangle-events/src/ingest.rs b/tangle-events/src/ingest.rs @@ -1,122 +1,69 @@ #[cfg(not(feature = "std"))] use alloc::format; #[cfg(not(feature = "std"))] -use alloc::{string::{String, ToString}, vec::Vec}; +use alloc::{ + string::{String, ToString}, + vec::Vec, +}; #[cfg(feature = "std")] -use base64::engine::general_purpose::URL_SAFE_NO_PAD; -#[cfg(feature = "std")] use base64::Engine; +#[cfg(feature = "std")] +use base64::engine::general_purpose::URL_SAFE_NO_PAD; -use radroots_events::kinds::{ - is_nip51_list_set_kind, - KIND_FARM, - KIND_PLOT, - KIND_PROFILE, -}; use radroots_events::RadrootsNostrEvent; +use radroots_events::kinds::{KIND_FARM, KIND_PLOT, KIND_PROFILE, is_nip51_list_set_kind}; use radroots_events_codec::farm::decode as farm_decode; use radroots_events_codec::list_set::decode as list_set_decode; use radroots_events_codec::plot::decode as plot_decode; use radroots_events_codec::profile::decode as profile_decode; use radroots_sql_core::SqlExecutor; use radroots_sql_core::error::SqlError; +use radroots_tangle_db::{ + farm, farm_gcs_location, farm_member, farm_member_claim, farm_tag, gcs_location, + nostr_event_state, nostr_profile, plot, plot_gcs_location, plot_tag, +}; use radroots_tangle_db_schema::farm::{ - FarmQueryBindValues, - IFarmFields, - IFarmFieldsFilter, - IFarmFindMany, + FarmQueryBindValues, IFarmFields, IFarmFieldsFilter, IFarmFieldsPartial, IFarmFindMany, IFarmUpdate, - IFarmFieldsPartial, }; use radroots_tangle_db_schema::farm_gcs_location::{ - IFarmGcsLocationFields, - IFarmGcsLocationFindMany, - IFarmGcsLocationFieldsFilter, - IFarmGcsLocationDelete, - IFarmGcsLocationFindOneArgs, - FarmGcsLocationQueryBindValues, + FarmGcsLocationQueryBindValues, IFarmGcsLocationDelete, IFarmGcsLocationFields, + IFarmGcsLocationFieldsFilter, IFarmGcsLocationFindMany, IFarmGcsLocationFindOneArgs, }; use radroots_tangle_db_schema::farm_member::{ - IFarmMemberFields, - IFarmMemberFindMany, - IFarmMemberFieldsFilter, - IFarmMemberDelete, - IFarmMemberFindOneArgs, - FarmMemberQueryBindValues, + FarmMemberQueryBindValues, IFarmMemberDelete, IFarmMemberFields, IFarmMemberFieldsFilter, + IFarmMemberFindMany, IFarmMemberFindOneArgs, }; use radroots_tangle_db_schema::farm_member_claim::{ - IFarmMemberClaimFields, - IFarmMemberClaimFindMany, - IFarmMemberClaimFieldsFilter, - IFarmMemberClaimDelete, - IFarmMemberClaimFindOneArgs, - FarmMemberClaimQueryBindValues, + FarmMemberClaimQueryBindValues, IFarmMemberClaimDelete, IFarmMemberClaimFields, + IFarmMemberClaimFieldsFilter, IFarmMemberClaimFindMany, IFarmMemberClaimFindOneArgs, }; use radroots_tangle_db_schema::farm_tag::{ - IFarmTagFields, - IFarmTagFindMany, - IFarmTagFieldsFilter, - IFarmTagDelete, + FarmTagQueryBindValues, IFarmTagDelete, IFarmTagFields, IFarmTagFieldsFilter, IFarmTagFindMany, IFarmTagFindOneArgs, - FarmTagQueryBindValues, -}; -use radroots_tangle_db_schema::gcs_location::{ - IGcsLocationFields, }; +use radroots_tangle_db_schema::gcs_location::IGcsLocationFields; use radroots_tangle_db_schema::nostr_event_state::{ - INostrEventStateFields, - INostrEventStateFindOne, - INostrEventStateFindOneArgs, - INostrEventStateUpdate, - INostrEventStateFieldsPartial, - NostrEventStateQueryBindValues, + INostrEventStateFields, INostrEventStateFieldsPartial, INostrEventStateFindOne, + INostrEventStateFindOneArgs, INostrEventStateUpdate, NostrEventStateQueryBindValues, }; use radroots_tangle_db_schema::nostr_profile::{ - INostrProfileFields, - INostrProfileFindOne, - INostrProfileFindOneArgs, - INostrProfileUpdate, - INostrProfileFieldsPartial, - NostrProfileQueryBindValues, + INostrProfileFields, INostrProfileFieldsPartial, INostrProfileFindOne, + INostrProfileFindOneArgs, INostrProfileUpdate, NostrProfileQueryBindValues, }; use radroots_tangle_db_schema::plot::{ - IPlotFields, - IPlotFieldsFilter, - IPlotFindMany, - IPlotUpdate, + IPlotFields, IPlotFieldsFilter, IPlotFieldsPartial, IPlotFindMany, IPlotUpdate, PlotQueryBindValues, - IPlotFieldsPartial, }; use radroots_tangle_db_schema::plot_gcs_location::{ - IPlotGcsLocationFields, - IPlotGcsLocationFindMany, - IPlotGcsLocationFieldsFilter, - IPlotGcsLocationDelete, - IPlotGcsLocationFindOneArgs, - PlotGcsLocationQueryBindValues, + IPlotGcsLocationDelete, IPlotGcsLocationFields, IPlotGcsLocationFieldsFilter, + IPlotGcsLocationFindMany, IPlotGcsLocationFindOneArgs, PlotGcsLocationQueryBindValues, }; use radroots_tangle_db_schema::plot_tag::{ - IPlotTagFields, - IPlotTagFindMany, - IPlotTagFieldsFilter, - IPlotTagDelete, - IPlotTagFindOneArgs, + IPlotTagDelete, IPlotTagFields, IPlotTagFieldsFilter, IPlotTagFindMany, IPlotTagFindOneArgs, PlotTagQueryBindValues, }; -use radroots_tangle_db::{ - farm, - farm_gcs_location, - farm_member, - farm_member_claim, - farm_tag, - gcs_location, - nostr_event_state, - nostr_profile, - plot, - plot_gcs_location, - plot_tag, -}; use serde_json::Value; use crate::error::RadrootsTangleEventsError; @@ -161,11 +108,14 @@ pub fn radroots_tangle_ingest_event_with_factory<E: SqlExecutor, F: RadrootsTang event: &RadrootsNostrEvent, factory: &F, ) -> Result<RadrootsTangleIngestOutcome, RadrootsTangleEventsError> { - exec.begin().map_err(|e| RadrootsTangleEventsError::from(radroots_types::types::IError::from(e)))?; + exec.begin() + .map_err(|e| RadrootsTangleEventsError::from(radroots_types::types::IError::from(e)))?; let outcome = match ingest_event_inner(exec, event, factory) { Ok(outcome) => { - exec.commit().map_err(|e| RadrootsTangleEventsError::from(radroots_types::types::IError::from(e)))?; + exec.commit().map_err(|e| { + RadrootsTangleEventsError::from(radroots_types::types::IError::from(e)) + })?; Ok(outcome) } Err(err) => { @@ -206,9 +156,9 @@ fn ingest_profile_event<E: SqlExecutor>( event.content.clone(), event.tags.clone(), )?; - let profile_type = metadata - .profile_type - .ok_or_else(|| RadrootsTangleEventsError::InvalidData("profile_type required".to_string()))?; + let profile_type = metadata.profile_type.ok_or_else(|| { + RadrootsTangleEventsError::InvalidData("profile_type required".to_string()) + })?; let d_tag = "".to_string(); let decision = event_state_decision(exec, event, &d_tag)?; @@ -306,7 +256,12 @@ fn ingest_farm_event<E: SqlExecutor, F: RadrootsTangleIdFactory>( location_region: None, location_country: None, }; - let existing = farm::find_many(exec, &IFarmFindMany { filter: Some(filter) })?; + let existing = farm::find_many( + exec, + &IFarmFindMany { + filter: Some(filter), + }, + )?; let location = farm.location.clone(); let (location_primary, location_city, location_region, location_country) = unpack_farm_location_strings(location.as_ref()); @@ -381,7 +336,12 @@ fn ingest_plot_event<E: SqlExecutor, F: RadrootsTangleIdFactory>( location_region: None, location_country: None, }; - let existing = plot::find_many(exec, &IPlotFindMany { filter: Some(filter) })?; + let existing = plot::find_many( + exec, + &IPlotFindMany { + filter: Some(filter), + }, + )?; let location = plot.location.clone(); let (location_primary, location_city, location_region, location_country) = unpack_plot_location_strings(location.as_ref()); @@ -432,7 +392,8 @@ fn ingest_list_set_event<E: SqlExecutor>( if event.kind != radroots_events::kinds::KIND_LIST_SET_GENERIC { return Ok(RadrootsTangleIngestOutcome::Skipped); } - let list_set = list_set_decode::list_set_from_tags(event.kind, event.content.clone(), &event.tags)?; + let list_set = + list_set_decode::list_set_from_tags(event.kind, event.content.clone(), &event.tags)?; if list_set.title.is_some() || list_set.description.is_some() || list_set.image.is_some() { return Err(RadrootsTangleEventsError::InvalidData( @@ -544,14 +505,23 @@ fn event_state_decision<E: SqlExecutor>( if let Some(state) = existing { if event.created_at < state.last_created_at { - return Ok(EventStateDecision { apply: false, content_hash }); + return Ok(EventStateDecision { + apply: false, + content_hash, + }); } if event.created_at == state.last_created_at && content_hash == state.content_hash { - return Ok(EventStateDecision { apply: false, content_hash }); + return Ok(EventStateDecision { + apply: false, + content_hash, + }); } } - Ok(EventStateDecision { apply: true, content_hash }) + Ok(EventStateDecision { + apply: true, + content_hash, + }) } fn find_farm_by_ref<E: SqlExecutor>( @@ -575,7 +545,12 @@ fn find_farm_by_ref<E: SqlExecutor>( location_region: None, location_country: None, }; - let result = farm::find_many(exec, &IFarmFindMany { filter: Some(filter) })?; + let result = farm::find_many( + exec, + &IFarmFindMany { + filter: Some(filter), + }, + )?; result .results .into_iter() @@ -951,7 +926,12 @@ enum ListSetRole { fn unpack_farm_location_strings( location: Option<&radroots_events::farm::RadrootsFarmLocation>, -) -> (Option<String>, Option<String>, Option<String>, Option<String>) { +) -> ( + Option<String>, + Option<String>, + Option<String>, + Option<String>, +) { match location { Some(location) => ( location.primary.clone(), @@ -965,7 +945,12 @@ fn unpack_farm_location_strings( fn unpack_plot_location_strings( location: Option<&radroots_events::plot::RadrootsPlotLocation>, -) -> (Option<String>, Option<String>, Option<String>, Option<String>) { +) -> ( + Option<String>, + Option<String>, + Option<String>, + Option<String>, +) { match location { Some(location) => ( location.primary.clone(), @@ -988,7 +973,12 @@ fn ensure_list_set_entries_tag( "domain:farm list set {label} must only include {expected} tags" ))); } - if entry.values.get(0).map(|v| v.trim().is_empty()).unwrap_or(true) { + if entry + .values + .get(0) + .map(|v| v.trim().is_empty()) + .unwrap_or(true) + { return Err(RadrootsTangleEventsError::InvalidData(format!( "domain:farm list set {label} contains empty entries" ))); diff --git a/tangle-events/src/lib.rs b/tangle-events/src/lib.rs @@ -4,43 +4,34 @@ #[cfg(not(feature = "std"))] extern crate alloc; -pub mod error; mod canonical; +pub mod emit; +pub mod error; mod event_state; mod geo; -pub mod emit; pub mod ingest; pub mod sync_state; pub mod types; -pub use error::RadrootsTangleEventsError; pub use emit::{ - radroots_tangle_sync_all, + radroots_tangle_farm_event, radroots_tangle_list_set_events, + radroots_tangle_membership_claim_events, radroots_tangle_plot_events, + radroots_tangle_profile_events, radroots_tangle_sync_all, radroots_tangle_sync_all_with_options, - radroots_tangle_farm_event, - radroots_tangle_list_set_events, - radroots_tangle_membership_claim_events, - radroots_tangle_plot_events, - radroots_tangle_profile_events, }; +pub use error::RadrootsTangleEventsError; pub use ingest::{ + RadrootsTangleIdFactory, RadrootsTangleIngestOutcome, radroots_tangle_ingest_event_state, radroots_tangle_ingest_event_with_factory, - radroots_tangle_ingest_event_state, - RadrootsTangleIngestOutcome, - RadrootsTangleIdFactory, }; -pub use sync_state::{radroots_tangle_sync_status, RadrootsTangleSyncStatus}; +pub use sync_state::{RadrootsTangleSyncStatus, radroots_tangle_sync_status}; pub use types::{ - RADROOTS_TANGLE_TRANSFER_VERSION, - RadrootsTangleEventDraft, - RadrootsTangleFarmSelector, - RadrootsTangleSyncBundle, - RadrootsTangleSyncOptions, - RadrootsTangleSyncRequest, + RADROOTS_TANGLE_TRANSFER_VERSION, RadrootsTangleEventDraft, RadrootsTangleFarmSelector, + RadrootsTangleSyncBundle, RadrootsTangleSyncOptions, RadrootsTangleSyncRequest, }; #[cfg(feature = "std")] -pub use ingest::{radroots_tangle_ingest_event, RadrootsTangleDefaultIdFactory}; +pub use ingest::{RadrootsTangleDefaultIdFactory, radroots_tangle_ingest_event}; #[cfg(test)] mod tests; diff --git a/tangle-events/src/sync_state.rs b/tangle-events/src/sync_state.rs @@ -1,5 +1,8 @@ #[cfg(not(feature = "std"))] -use alloc::{collections::BTreeMap, string::{String, ToString}}; +use alloc::{ + collections::BTreeMap, + string::{String, ToString}, +}; #[cfg(feature = "std")] use std::collections::BTreeMap; @@ -21,8 +24,7 @@ pub struct RadrootsTangleSyncStatus { pub fn radroots_tangle_sync_status<E: SqlExecutor>( exec: &E, ) -> Result<RadrootsTangleSyncStatus, RadrootsTangleEventsError> { - let farms = radroots_tangle_db::farm::find_many(exec, &IFarmFindMany { filter: None })? - .results; + let farms = radroots_tangle_db::farm::find_many(exec, &IFarmFindMany { filter: None })?.results; let mut expected: BTreeMap<String, String> = BTreeMap::new(); for farm in farms { diff --git a/tangle-events/src/tests.rs b/tangle-events/src/tests.rs @@ -1,14 +1,15 @@ +use crate::{ + RADROOTS_TANGLE_TRANSFER_VERSION, RadrootsTangleFarmSelector, RadrootsTangleSyncRequest, + radroots_tangle_sync_all, +}; use radroots_events::farm::{RadrootsGeoJsonPoint, RadrootsGeoJsonPolygon}; use radroots_events::kinds::{KIND_FARM, KIND_LIST_SET_GENERIC, KIND_PLOT, KIND_PROFILE}; use radroots_sql_core::SqliteExecutor; use radroots_sql_core::error::SqlError; -use crate::{ - radroots_tangle_sync_all, - RadrootsTangleFarmSelector, - RadrootsTangleSyncRequest, - RADROOTS_TANGLE_TRANSFER_VERSION, +use radroots_tangle_db::{ + farm, farm_gcs_location, farm_member, farm_member_claim, farm_tag, gcs_location, migrations, + nostr_profile, plot, plot_gcs_location, plot_tag, }; -use radroots_types::types::IError; use radroots_tangle_db_schema::farm::IFarmFields; use radroots_tangle_db_schema::farm_gcs_location::IFarmGcsLocationFields; use radroots_tangle_db_schema::farm_member::IFarmMemberFields; @@ -19,19 +20,7 @@ use radroots_tangle_db_schema::nostr_profile::INostrProfileFields; use radroots_tangle_db_schema::plot::IPlotFields; use radroots_tangle_db_schema::plot_gcs_location::IPlotGcsLocationFields; use radroots_tangle_db_schema::plot_tag::IPlotTagFields; -use radroots_tangle_db::{ - farm, - farm_gcs_location, - farm_member, - farm_member_claim, - farm_tag, - gcs_location, - migrations, - nostr_profile, - plot, - plot_gcs_location, - plot_tag, -}; +use radroots_types::types::IError; fn unwrap_sql<T>(result: Result<T, IError<SqlError>>, label: &str) -> T { match result { @@ -228,11 +217,19 @@ fn sync_all_emits_expected_order() { assert_eq!(bundle.version, RADROOTS_TANGLE_TRANSFER_VERSION); assert_eq!(bundle.events.len(), 9); - let kinds = bundle.events.iter().map(|event| event.kind).collect::<Vec<_>>(); + let kinds = bundle + .events + .iter() + .map(|event| event.kind) + .collect::<Vec<_>>(); assert_eq!(kinds[0], KIND_PROFILE); assert_eq!(kinds[1], KIND_PROFILE); assert_eq!(kinds[2], KIND_FARM); assert_eq!(kinds[3], KIND_PLOT); - assert!(kinds[4..8].iter().all(|kind| *kind == KIND_LIST_SET_GENERIC)); + assert!( + kinds[4..8] + .iter() + .all(|kind| *kind == KIND_LIST_SET_GENERIC) + ); assert_eq!(kinds[8], KIND_LIST_SET_GENERIC); }