lib

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

commit 5eb855c6ed9d8bd68ff3e39bca634ffd52d3f904
parent 3b9264644a76602d64b92c7f525769ec530b2faa
Author: triesap <tyson@radroots.org>
Date:   Wed, 24 Jun 2026 23:13:56 +0000

dto: merge descriptor generation updates

Diffstat:
MCargo.lock | 44++++++++++++++++++++++++++++++++++++++++++++
MCargo.toml | 1+
Mcrates/events/Cargo.toml | 3++-
Mcrates/events/src/account.rs | 1+
Mcrates/events/src/app_data.rs | 1+
Mcrates/events/src/coop.rs | 3+++
Mcrates/events/src/document.rs | 2++
Mcrates/events/src/dto.rs | 1823++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Mcrates/events/src/farm.rs | 6++++++
Mcrates/events/src/follow.rs | 2++
Mcrates/events/src/geochat.rs | 1+
Mcrates/events/src/gift_wrap.rs | 2++
Mcrates/events/src/job.rs | 12++++++++++++
Mcrates/events/src/job_feedback.rs | 1+
Mcrates/events/src/job_request.rs | 3+++
Mcrates/events/src/job_result.rs | 1+
Mcrates/events/src/kinds.rs | 31+++++++++++++++++++++++++++++++
Mcrates/events/src/list.rs | 2++
Mcrates/events/src/list_set.rs | 1+
Mcrates/events/src/listing.rs | 1+
Mcrates/events/src/message.rs | 2++
Mcrates/events/src/message_file.rs | 3+++
Mcrates/events/src/order.rs | 39++++++++++++++++++++++++++++++++++++---
Mcrates/events/src/order_economics.rs | 31+++++++++++++++++++++++++++++++
Mcrates/events/src/plot.rs | 3+++
Mcrates/events/src/profile.rs | 7+++++++
Mcrates/events/src/relay_document.rs | 1+
Mcrates/events/src/resource_area.rs | 3+++
Mcrates/events/src/resource_cap.rs | 1+
Mcrates/events/src/seal.rs | 1+
Mcrates/events/src/trade_validation.rs | 10++++++++++
Mcrates/events_indexed/Cargo.toml | 3+++
Acrates/events_indexed/src/dto.rs | 198+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/events_indexed/src/lib.rs | 2++
Mcrates/events_indexed/src/manifest.rs | 2++
Mcrates/events_indexed/src/types.rs | 1+
Mcrates/replica_db_schema/Cargo.toml | 2++
Acrates/replica_db_schema/src/dto.rs | 2204+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/replica_db_schema/src/lib.rs | 3+++
Mcrates/trade/Cargo.toml | 10++++++++++
Acrates/trade/src/dto.rs | 315+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/trade/src/lib.rs | 2++
42 files changed, 4763 insertions(+), 21 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -1500,6 +1500,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] +name = "dto_bindgen" +version = "0.1.0" +source = "git+https://github.com/triesap/dto_bindgen?rev=96ed6c691aacab31860828d25da2e0167b13d92c#96ed6c691aacab31860828d25da2e0167b13d92c" +dependencies = [ + "dto_bindgen_backend_python", + "dto_bindgen_backend_ts", + "dto_bindgen_core", + "dto_bindgen_macros", + "sha2", +] + +[[package]] +name = "dto_bindgen_backend_python" +version = "0.1.0" +source = "git+https://github.com/triesap/dto_bindgen?rev=96ed6c691aacab31860828d25da2e0167b13d92c#96ed6c691aacab31860828d25da2e0167b13d92c" +dependencies = [ + "dto_bindgen_core", +] + +[[package]] +name = "dto_bindgen_backend_ts" +version = "0.1.0" +source = "git+https://github.com/triesap/dto_bindgen?rev=96ed6c691aacab31860828d25da2e0167b13d92c#96ed6c691aacab31860828d25da2e0167b13d92c" +dependencies = [ + "dto_bindgen_core", +] + +[[package]] name = "dto_bindgen_core" version = "0.1.0" source = "git+https://github.com/triesap/dto_bindgen?rev=96ed6c691aacab31860828d25da2e0167b13d92c#96ed6c691aacab31860828d25da2e0167b13d92c" @@ -1514,6 +1542,16 @@ dependencies = [ ] [[package]] +name = "dto_bindgen_macros" +version = "0.1.0" +source = "git+https://github.com/triesap/dto_bindgen?rev=96ed6c691aacab31860828d25da2e0167b13d92c#96ed6c691aacab31860828d25da2e0167b13d92c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] name = "dynasm" version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4261,6 +4299,7 @@ dependencies = [ name = "radroots_events" version = "0.1.0-alpha.2" dependencies = [ + "dto_bindgen", "dto_bindgen_core", "hex", "radroots_core", @@ -4284,6 +4323,8 @@ dependencies = [ name = "radroots_events_indexed" version = "0.1.0-alpha.2" dependencies = [ + "dto_bindgen", + "dto_bindgen_core", "serde", "serde_json", ] @@ -4524,6 +4565,7 @@ dependencies = [ name = "radroots_replica_db_schema" version = "0.1.0-alpha.2" dependencies = [ + "dto_bindgen_core", "radroots_types", "serde", "serde_json", @@ -4779,6 +4821,8 @@ name = "radroots_trade" version = "0.1.0-alpha.2" dependencies = [ "base64 0.22.1", + "dto_bindgen", + "dto_bindgen_core", "hex", "radroots_authority", "radroots_core", diff --git a/Cargo.toml b/Cargo.toml @@ -58,6 +58,7 @@ homepage = "https://radroots.org" readme = "README" [workspace.dependencies] +dto_bindgen = { git = "https://github.com/triesap/dto_bindgen", rev = "96ed6c691aacab31860828d25da2e0167b13d92c", package = "dto_bindgen" } dto_bindgen_core = { git = "https://github.com/triesap/dto_bindgen", rev = "96ed6c691aacab31860828d25da2e0167b13d92c", package = "dto_bindgen_core" } radroots_core = { path = "crates/core", version = "0.1.0-alpha.2", default-features = false } radroots_events = { path = "crates/events", version = "0.1.0-alpha.2", default-features = false } diff --git a/crates/events/Cargo.toml b/crates/events/Cargo.toml @@ -14,11 +14,12 @@ readme = "README" [features] default = ["std", "serde"] -dto-bindgen = ["std", "serde", "dep:dto_bindgen_core", "radroots_core/dto-bindgen"] +dto-bindgen = ["std", "serde", "dep:dto_bindgen", "dep:dto_bindgen_core", "radroots_core/dto-bindgen"] std = ["radroots_core/std"] serde = ["dep:serde", "radroots_core/serde"] [dependencies] +dto_bindgen = { workspace = true, optional = true } dto_bindgen_core = { workspace = true, optional = true } radroots_core = { workspace = true, default-features = false } hex = { version = "0.4", default-features = false, features = ["alloc"] } diff --git a/crates/events/src/account.rs b/crates/events/src/account.rs @@ -5,6 +5,7 @@ use alloc::string::String; pub const KIND_ACCOUNT_CLAIM: u32 = KIND_ACCOUNT_CLAIM_EVENT; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsAccountClaim { diff --git a/crates/events/src/app_data.rs b/crates/events/src/app_data.rs @@ -7,6 +7,7 @@ use alloc::string::String; pub const KIND_APP_DATA: u32 = KIND_APP_DATA_EVENT; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsAppData { diff --git a/crates/events/src/coop.rs b/crates/events/src/coop.rs @@ -5,6 +5,7 @@ use crate::farm::RadrootsGcsLocation; #[cfg(not(feature = "std"))] use alloc::{string::String, vec::Vec}; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsCoop { @@ -18,6 +19,7 @@ pub struct RadrootsCoop { pub tags: Option<Vec<String>>, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsCoopRef { @@ -25,6 +27,7 @@ pub struct RadrootsCoopRef { pub d_tag: String, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsCoopLocation { diff --git a/crates/events/src/document.rs b/crates/events/src/document.rs @@ -3,6 +3,7 @@ #[cfg(not(feature = "std"))] use alloc::{string::String, vec::Vec}; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsDocumentSubject { @@ -10,6 +11,7 @@ pub struct RadrootsDocumentSubject { pub address: Option<String>, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsDocument { diff --git a/crates/events/src/dto.rs b/crates/events/src/dto.rs @@ -1,23 +1,208 @@ use dto_bindgen_core::{ - DescribeCtx, Dto, FieldDef, FieldPresence, IdentName, RootDescriptor, RustTypeId, SourceSpan, - StructDef, TargetFieldNames, TypeDef, TypeRef, WireFieldNames, + DescribeCtx, Dto, EnumDef, EnumRepr, FieldDef, FieldPresence, GenericParam, IdentName, IntRepr, + RootDescriptor, RustTypeId, SourceSpan, StructDef, TargetFieldNames, TypeDef, TypeRef, + VariantDef, VariantShape, WireFieldNames, }; +use radroots_core::RadrootsCoreDiscountValue; use crate::{ RadrootsNostrEvent, RadrootsNostrEventPtr, RadrootsNostrEventRef, - listing::{RadrootsListingImage, RadrootsListingImageSize, RadrootsListingProduct}, + account::RadrootsAccountClaim, + app_data::RadrootsAppData, + comment::RadrootsComment, + coop::{RadrootsCoop, RadrootsCoopLocation, RadrootsCoopRef}, + document::{RadrootsDocument, RadrootsDocumentSubject}, + farm::{ + RadrootsFarm, RadrootsFarmLocation, RadrootsFarmRef, RadrootsGcsLocation, + RadrootsGeoJsonPoint, RadrootsGeoJsonPolygon, + }, + follow::{RadrootsFollow, RadrootsFollowProfile}, + geochat::RadrootsGeoChat, + gift_wrap::{RadrootsGiftWrap, RadrootsGiftWrapRecipient}, + ids::{ + RadrootsDTag, RadrootsEventId, RadrootsInventoryBinId, RadrootsListingAddress, + RadrootsOrderId, RadrootsOrderQuoteId, RadrootsOrderRevisionId, RadrootsPublicKey, + }, + job::{JobFeedbackStatus, JobInputType, JobPaymentRequest}, + job_feedback::RadrootsJobFeedback, + job_request::{RadrootsJobInput, RadrootsJobParam, RadrootsJobRequest}, + job_result::RadrootsJobResult, + list::{RadrootsList, RadrootsListEntry}, + list_set::RadrootsListSet, + listing::{ + RadrootsListing, RadrootsListingAvailability, RadrootsListingBin, + RadrootsListingDeliveryMethod, RadrootsListingImage, RadrootsListingImageSize, + RadrootsListingLocation, RadrootsListingProduct, RadrootsListingStatus, + }, + message::{RadrootsMessage, RadrootsMessageRecipient}, + message_file::{RadrootsMessageFile, RadrootsMessageFileDimensions}, + order::{ + RadrootsCommercialDomain, RadrootsListingParseError, RadrootsOrderCancellation, + RadrootsOrderDecision, RadrootsOrderDecisionOutcome, RadrootsOrderEventType, + RadrootsOrderInventoryCommitment, RadrootsOrderRequest, RadrootsOrderRevisionDecision, + RadrootsOrderRevisionOutcome, RadrootsOrderRevisionProposal, + }, + order_economics::{ + RadrootsOrderEconomicActor, RadrootsOrderEconomicEffect, RadrootsOrderEconomicItem, + RadrootsOrderEconomicLine, RadrootsOrderEconomicLineKind, RadrootsOrderEconomicTotals, + RadrootsOrderEconomics, RadrootsOrderItem, RadrootsOrderPricingBasis, + }, + plot::{RadrootsPlot, RadrootsPlotLocation, RadrootsPlotRef}, + post::RadrootsPost, + profile::{RadrootsProfile, RadrootsProfileType}, + reaction::RadrootsReaction, + relay_document::RadrootsRelayDocument, + resource_area::{RadrootsResourceArea, RadrootsResourceAreaLocation, RadrootsResourceAreaRef}, + resource_cap::{RadrootsResourceHarvestCap, RadrootsResourceHarvestProduct}, + seal::RadrootsSeal, + trade_validation::{ + RadrootsTradeValidationListingError, RadrootsTradeValidationListingRequest, + RadrootsTradeValidationListingResult, + }, }; -pub fn dto_roots() -> [RootDescriptor; 5] { - [ +pub fn dto_roots() -> Vec<RootDescriptor> { + vec![ + RootDescriptor::new::<JobFeedbackStatus>(), + RootDescriptor::new::<JobInputType>(), + RootDescriptor::new::<JobPaymentRequest>(), + RootDescriptor::new::<RadrootsAccountClaim>(), + RootDescriptor::new::<RadrootsActiveTradeEnvelopeDto>(), + RootDescriptor::new::<RadrootsAppData>(), + RootDescriptor::new::<RadrootsComment>(), + RootDescriptor::new::<RadrootsCoop>(), + RootDescriptor::new::<RadrootsCoopLocation>(), + RootDescriptor::new::<RadrootsCoopRef>(), + RootDescriptor::new::<RadrootsDocument>(), + RootDescriptor::new::<RadrootsDocumentSubject>(), + RootDescriptor::new::<RadrootsFarm>(), + RootDescriptor::new::<RadrootsFarmLocation>(), + RootDescriptor::new::<RadrootsFarmRef>(), + RootDescriptor::new::<RadrootsFollow>(), + RootDescriptor::new::<RadrootsFollowProfile>(), + RootDescriptor::new::<RadrootsGcsLocation>(), + RootDescriptor::new::<RadrootsGeoChat>(), + RootDescriptor::new::<RadrootsGeoJsonPoint>(), + RootDescriptor::new::<RadrootsGeoJsonPolygon>(), + RootDescriptor::new::<RadrootsGiftWrap>(), + RootDescriptor::new::<RadrootsGiftWrapRecipient>(), + RootDescriptor::new::<RadrootsJobFeedback>(), + RootDescriptor::new::<RadrootsJobInput>(), + RootDescriptor::new::<RadrootsJobParam>(), + RootDescriptor::new::<RadrootsJobRequest>(), + RootDescriptor::new::<RadrootsJobResult>(), + RootDescriptor::new::<RadrootsList>(), + RootDescriptor::new::<RadrootsListEntry>(), + RootDescriptor::new::<RadrootsListSet>(), + RootDescriptor::new::<RadrootsListing>(), + RootDescriptor::new::<RadrootsListingAvailability>(), + RootDescriptor::new::<RadrootsListingBin>(), + RootDescriptor::new::<RadrootsListingDeliveryMethod>(), RootDescriptor::new::<RadrootsNostrEvent>(), RootDescriptor::new::<RadrootsNostrEventRef>(), RootDescriptor::new::<RadrootsNostrEventPtr>(), + RootDescriptor::new::<RadrootsListingLocation>(), RootDescriptor::new::<RadrootsListingProduct>(), + RootDescriptor::new::<RadrootsListingStatus>(), RootDescriptor::new::<RadrootsListingImage>(), + RootDescriptor::new::<RadrootsMessage>(), + RootDescriptor::new::<RadrootsMessageFile>(), + RootDescriptor::new::<RadrootsMessageFileDimensions>(), + RootDescriptor::new::<RadrootsMessageRecipient>(), + RootDescriptor::new::<RadrootsPlot>(), + RootDescriptor::new::<RadrootsPlotLocation>(), + RootDescriptor::new::<RadrootsPlotRef>(), + RootDescriptor::new::<RadrootsPost>(), + RootDescriptor::new::<RadrootsProfile>(), + RootDescriptor::new::<RadrootsProfileType>(), + RootDescriptor::new::<RadrootsReaction>(), + RootDescriptor::new::<RadrootsRelayDocument>(), + RootDescriptor::new::<RadrootsResourceArea>(), + RootDescriptor::new::<RadrootsResourceAreaLocation>(), + RootDescriptor::new::<RadrootsResourceAreaRef>(), + RootDescriptor::new::<RadrootsResourceHarvestCap>(), + RootDescriptor::new::<RadrootsResourceHarvestProduct>(), + RootDescriptor::new::<RadrootsSeal>(), + RootDescriptor::new::<RadrootsTradeAnswerDto>(), + RootDescriptor::new::<RadrootsTradeDiscountDecisionDto>(), + RootDescriptor::new::<RadrootsTradeDiscountOfferDto>(), + RootDescriptor::new::<RadrootsTradeDiscountRequestDto>(), + RootDescriptor::new::<RadrootsCommercialDomain>(), + RootDescriptor::new::<RadrootsOrderEconomicActor>(), + RootDescriptor::new::<RadrootsOrderEconomicEffect>(), + RootDescriptor::new::<RadrootsOrderEconomicLineKind>(), + RootDescriptor::new::<RadrootsTradeEnvelopeDto>(), + RootDescriptor::new::<RadrootsOrderInventoryCommitment>(), + RootDescriptor::new::<RadrootsTradeListingCancelDto>(), + RootDescriptor::new::<RadrootsListingParseError>(), + RootDescriptor::new::<RadrootsTradeValidationListingRequest>(), + RootDescriptor::new::<RadrootsTradeValidationListingResult>(), + RootDescriptor::new::<RadrootsTradeValidationListingError>(), + RootDescriptor::new::<RadrootsTradeMessagePayloadDto>(), + RootDescriptor::new::<RadrootsTradeMessageTypeDto>(), + RootDescriptor::new::<RadrootsOrderCancellation>(), + RootDescriptor::new::<RadrootsTradeOrderChangeDto>(), + RootDescriptor::new::<RadrootsOrderDecisionOutcome>(), + RootDescriptor::new::<RadrootsOrderDecision>(), + RootDescriptor::new::<RadrootsOrderEconomicItem>(), + RootDescriptor::new::<RadrootsOrderEconomicLine>(), + RootDescriptor::new::<RadrootsOrderEconomicTotals>(), + RootDescriptor::new::<RadrootsOrderEconomics>(), + RootDescriptor::new::<RadrootsOrderItem>(), + RootDescriptor::new::<RadrootsOrderRequest>(), + RootDescriptor::new::<RadrootsTradeOrderResponseDto>(), + RootDescriptor::new::<RadrootsTradeOrderRevisionDto>(), + RootDescriptor::new::<RadrootsOrderRevisionOutcome>(), + RootDescriptor::new::<RadrootsOrderRevisionDecision>(), + RootDescriptor::new::<RadrootsOrderRevisionProposal>(), + RootDescriptor::new::<RadrootsTradeOrderRevisionResponseDto>(), + RootDescriptor::new::<RadrootsTradeOrderStatusDto>(), + RootDescriptor::new::<RadrootsOrderPricingBasis>(), + RootDescriptor::new::<RadrootsTradeQuestionDto>(), + RootDescriptor::new::<RadrootsTradeTransportLaneDto>(), ] } +pub struct RadrootsActiveTradeEnvelopeDto; +pub struct RadrootsTradeAnswerDto; +pub struct RadrootsTradeDiscountDecisionDto; +pub struct RadrootsTradeDiscountOfferDto; +pub struct RadrootsTradeDiscountRequestDto; +pub struct RadrootsTradeEnvelopeDto; +pub struct RadrootsTradeListingCancelDto; +pub struct RadrootsTradeMessagePayloadDto; +pub struct RadrootsTradeMessageTypeDto; +pub struct RadrootsTradeOrderChangeDto; +pub struct RadrootsTradeOrderResponseDto; +pub struct RadrootsTradeOrderRevisionDto; +pub struct RadrootsTradeOrderRevisionResponseDto; +pub struct RadrootsTradeOrderStatusDto; +pub struct RadrootsTradeQuestionDto; +pub struct RadrootsTradeTransportLaneDto; + +macro_rules! string_dto { + ($($ty:ty),+ $(,)?) => { + $( + impl Dto for $ty { + fn describe(_ctx: &mut DescribeCtx) -> TypeRef { + TypeRef::String + } + } + )+ + }; +} + +string_dto!( + RadrootsDTag, + RadrootsEventId, + RadrootsInventoryBinId, + RadrootsListingAddress, + RadrootsOrderId, + RadrootsOrderQuoteId, + RadrootsOrderRevisionId, + RadrootsPublicKey, +); + impl Dto for RadrootsNostrEvent { fn describe(ctx: &mut DescribeCtx) -> TypeRef { let def = StructDef::new( @@ -106,14 +291,14 @@ impl Dto for RadrootsNostrEventRef { "crates/events/src/lib.rs", 67, )) - .with_field(field( + .with_field(optional_nullable_field( "d_tag", "d_tag", <Option<String> as Dto>::describe(ctx), "crates/events/src/lib.rs", 68, )) - .with_field(field( + .with_field(optional_nullable_field( "relays", "relays", <Option<Vec<String>> as Dto>::describe(ctx), @@ -138,7 +323,7 @@ impl Dto for RadrootsNostrEventPtr { "crates/events/src/lib.rs", 75, )) - .with_field(field( + .with_field(optional_nullable_field( "relays", "relays", <Option<String> as Dto>::describe(ctx), @@ -177,42 +362,42 @@ impl Dto for RadrootsListingProduct { "crates/events/src/listing.rs", 84, )) - .with_field(nullable_field( + .with_field(optional_nullable_field( "summary", "summary", <Option<String> as Dto>::describe(ctx), "crates/events/src/listing.rs", 85, )) - .with_field(nullable_field( + .with_field(optional_nullable_field( "process", "process", <Option<String> as Dto>::describe(ctx), "crates/events/src/listing.rs", 86, )) - .with_field(nullable_field( + .with_field(optional_nullable_field( "lot", "lot", <Option<String> as Dto>::describe(ctx), "crates/events/src/listing.rs", 87, )) - .with_field(nullable_field( + .with_field(optional_nullable_field( "location", "location", <Option<String> as Dto>::describe(ctx), "crates/events/src/listing.rs", 88, )) - .with_field(nullable_field( + .with_field(optional_nullable_field( "profile", "profile", <Option<String> as Dto>::describe(ctx), "crates/events/src/listing.rs", 89, )) - .with_field(nullable_field( + .with_field(optional_nullable_field( "year", "year", <Option<String> as Dto>::describe(ctx), @@ -223,6 +408,73 @@ impl Dto for RadrootsListingProduct { } } +impl Dto for RadrootsListingBin { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef::new( + "RadrootsListingBin", + "RadrootsListingBin", + span("crates/events/src/listing.rs", 101), + ) + .with_field(field( + "bin_id", + "bin_id", + RadrootsInventoryBinId::describe(ctx), + "crates/events/src/listing.rs", + 102, + )) + .with_field(field( + "quantity", + "quantity", + radroots_core::RadrootsCoreQuantity::describe(ctx), + "crates/events/src/listing.rs", + 103, + )) + .with_field(field( + "price_per_canonical_unit", + "price_per_canonical_unit", + radroots_core::RadrootsCoreQuantityPrice::describe(ctx), + "crates/events/src/listing.rs", + 104, + )) + .with_field(optional_nullable_field( + "display_amount", + "display_amount", + TypeRef::option(core_decimal(ctx)), + "crates/events/src/listing.rs", + 105, + )) + .with_field(optional_nullable_field( + "display_unit", + "display_unit", + <Option<radroots_core::RadrootsCoreUnit> as Dto>::describe(ctx), + "crates/events/src/listing.rs", + 106, + )) + .with_field(optional_nullable_field( + "display_label", + "display_label", + <Option<String> as Dto>::describe(ctx), + "crates/events/src/listing.rs", + 107, + )) + .with_field(optional_nullable_field( + "display_price", + "display_price", + <Option<radroots_core::RadrootsCoreMoney> as Dto>::describe(ctx), + "crates/events/src/listing.rs", + 108, + )) + .with_field(optional_nullable_field( + "display_price_unit", + "display_price_unit", + <Option<radroots_core::RadrootsCoreUnit> as Dto>::describe(ctx), + "crates/events/src/listing.rs", + 109, + )); + register(ctx, "RadrootsListingBin", TypeDef::Struct(def)) + } +} + impl Dto for RadrootsListingImageSize { fn describe(ctx: &mut DescribeCtx) -> TypeRef { let def = StructDef::new( @@ -263,7 +515,7 @@ impl Dto for RadrootsListingImage { "crates/events/src/listing.rs", 127, )) - .with_field(nullable_field( + .with_field(optional_nullable_field( "size", "size", TypeRef::option(size), @@ -274,18 +526,1518 @@ impl Dto for RadrootsListingImage { } } +impl Dto for RadrootsListingAvailability { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = EnumDef::new( + "RadrootsListingAvailability", + "RadrootsListingAvailability", + EnumRepr::Adjacent { + tag: "kind".to_owned(), + content: "amount".to_owned(), + }, + span("crates/events/src/listing.rs", 20), + ) + .with_variant(VariantDef::new( + "Window", + "window", + VariantShape::Struct(vec![ + optional_nullable_field( + "start", + "start", + <Option<u64> as Dto>::describe(ctx), + "crates/events/src/listing.rs", + 21, + ) + .with_int_repr(IntRepr::JsonNumberUnsafe), + optional_nullable_field( + "end", + "end", + <Option<u64> as Dto>::describe(ctx), + "crates/events/src/listing.rs", + 22, + ) + .with_int_repr(IntRepr::JsonNumberUnsafe), + ]), + span("crates/events/src/listing.rs", 21), + )) + .with_variant(VariantDef::new( + "Status", + "status", + VariantShape::Struct(vec![field( + "status", + "status", + RadrootsListingStatus::describe(ctx), + "crates/events/src/listing.rs", + 24, + )]), + span("crates/events/src/listing.rs", 24), + )); + register(ctx, "RadrootsListingAvailability", TypeDef::Enum(def)) + } +} + +impl Dto for RadrootsListingStatus { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = EnumDef::new( + "RadrootsListingStatus", + "RadrootsListingStatus", + EnumRepr::Adjacent { + tag: "kind".to_owned(), + content: "amount".to_owned(), + }, + span("crates/events/src/listing.rs", 36), + ) + .with_variant(VariantDef::new( + "Active", + "active", + VariantShape::Unit, + span("crates/events/src/listing.rs", 37), + )) + .with_variant(VariantDef::new( + "Sold", + "sold", + VariantShape::Unit, + span("crates/events/src/listing.rs", 38), + )) + .with_variant(VariantDef::new( + "Other", + "other", + VariantShape::Struct(vec![field( + "value", + "value", + String::describe(ctx), + "crates/events/src/listing.rs", + 39, + )]), + span("crates/events/src/listing.rs", 39), + )); + register(ctx, "RadrootsListingStatus", TypeDef::Enum(def)) + } +} + +impl Dto for RadrootsListingDeliveryMethod { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = EnumDef::new( + "RadrootsListingDeliveryMethod", + "RadrootsListingDeliveryMethod", + EnumRepr::Adjacent { + tag: "kind".to_owned(), + content: "amount".to_owned(), + }, + span("crates/events/src/listing.rs", 48), + ) + .with_variant(VariantDef::new( + "Pickup", + "pickup", + VariantShape::Unit, + span("crates/events/src/listing.rs", 49), + )) + .with_variant(VariantDef::new( + "LocalDelivery", + "local_delivery", + VariantShape::Unit, + span("crates/events/src/listing.rs", 50), + )) + .with_variant(VariantDef::new( + "Shipping", + "shipping", + VariantShape::Unit, + span("crates/events/src/listing.rs", 51), + )) + .with_variant(VariantDef::new( + "Other", + "other", + VariantShape::Struct(vec![field( + "method", + "method", + String::describe(ctx), + "crates/events/src/listing.rs", + 52, + )]), + span("crates/events/src/listing.rs", 52), + )); + register(ctx, "RadrootsListingDeliveryMethod", TypeDef::Enum(def)) + } +} + +impl Dto for RadrootsListing { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef::new( + "RadrootsListing", + "RadrootsListing", + span("crates/events/src/listing.rs", 57), + ) + .with_field(field( + "d_tag", + "d_tag", + RadrootsDTag::describe(ctx), + "crates/events/src/listing.rs", + 58, + )) + .with_field( + optional_nullable_field( + "published_at", + "published_at", + <Option<u64> as Dto>::describe(ctx), + "crates/events/src/listing.rs", + 63, + ) + .with_presence(FieldPresence::optional_nullable_skip_if_none()) + .with_int_repr(IntRepr::JsonNumberUnsafe), + ) + .with_field(field( + "farm", + "farm", + RadrootsFarmRef::describe(ctx), + "crates/events/src/listing.rs", + 68, + )) + .with_field(field( + "product", + "product", + RadrootsListingProduct::describe(ctx), + "crates/events/src/listing.rs", + 69, + )) + .with_field(field( + "primary_bin_id", + "primary_bin_id", + RadrootsInventoryBinId::describe(ctx), + "crates/events/src/listing.rs", + 70, + )) + .with_field(field( + "bins", + "bins", + <Vec<RadrootsListingBin> as Dto>::describe(ctx), + "crates/events/src/listing.rs", + 71, + )) + .with_field(optional_nullable_field( + "resource_area", + "resource_area", + <Option<RadrootsResourceAreaRef> as Dto>::describe(ctx), + "crates/events/src/listing.rs", + 72, + )) + .with_field(optional_nullable_field( + "plot", + "plot", + <Option<RadrootsPlotRef> as Dto>::describe(ctx), + "crates/events/src/listing.rs", + 73, + )) + .with_field(optional_nullable_field( + "discounts", + "discounts", + <Option<Vec<radroots_core::RadrootsCoreDiscount>> as Dto>::describe(ctx), + "crates/events/src/listing.rs", + 74, + )) + .with_field(optional_nullable_field( + "inventory_available", + "inventory_available", + TypeRef::option(core_decimal(ctx)), + "crates/events/src/listing.rs", + 75, + )) + .with_field(optional_nullable_field( + "availability", + "availability", + <Option<RadrootsListingAvailability> as Dto>::describe(ctx), + "crates/events/src/listing.rs", + 76, + )) + .with_field(optional_nullable_field( + "delivery_method", + "delivery_method", + <Option<RadrootsListingDeliveryMethod> as Dto>::describe(ctx), + "crates/events/src/listing.rs", + 77, + )) + .with_field(optional_nullable_field( + "location", + "location", + <Option<RadrootsListingLocation> as Dto>::describe(ctx), + "crates/events/src/listing.rs", + 78, + )) + .with_field(optional_nullable_field( + "images", + "images", + <Option<Vec<RadrootsListingImage>> as Dto>::describe(ctx), + "crates/events/src/listing.rs", + 79, + )); + register(ctx, "RadrootsListing", TypeDef::Struct(def)) + } +} + +impl Dto for RadrootsResourceHarvestCap { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef::new( + "RadrootsResourceHarvestCap", + "RadrootsResourceHarvestCap", + span("crates/events/src/resource_cap.rs", 20), + ) + .with_field(field( + "d_tag", + "d_tag", + String::describe(ctx), + "crates/events/src/resource_cap.rs", + 21, + )) + .with_field(field( + "resource_area", + "resource_area", + RadrootsResourceAreaRef::describe(ctx), + "crates/events/src/resource_cap.rs", + 22, + )) + .with_field(field( + "product", + "product", + RadrootsResourceHarvestProduct::describe(ctx), + "crates/events/src/resource_cap.rs", + 23, + )) + .with_field( + field( + "start", + "start", + u64::describe(ctx), + "crates/events/src/resource_cap.rs", + 24, + ) + .with_int_repr(IntRepr::NonJsonBigint), + ) + .with_field( + field( + "end", + "end", + u64::describe(ctx), + "crates/events/src/resource_cap.rs", + 25, + ) + .with_int_repr(IntRepr::NonJsonBigint), + ) + .with_field(field( + "cap_quantity", + "cap_quantity", + radroots_core::RadrootsCoreQuantity::describe(ctx), + "crates/events/src/resource_cap.rs", + 26, + )) + .with_field(optional_nullable_field( + "display_amount", + "display_amount", + TypeRef::option(core_decimal(ctx)), + "crates/events/src/resource_cap.rs", + 27, + )) + .with_field(optional_nullable_field( + "display_unit", + "display_unit", + <Option<radroots_core::RadrootsCoreUnit> as Dto>::describe(ctx), + "crates/events/src/resource_cap.rs", + 28, + )) + .with_field(optional_nullable_field( + "display_label", + "display_label", + <Option<String> as Dto>::describe(ctx), + "crates/events/src/resource_cap.rs", + 29, + )) + .with_field(optional_nullable_field( + "tags", + "tags", + <Option<Vec<String>> as Dto>::describe(ctx), + "crates/events/src/resource_cap.rs", + 30, + )); + register(ctx, "RadrootsResourceHarvestCap", TypeDef::Struct(def)) + } +} + +impl Dto for RadrootsComment { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let event_ref = RadrootsNostrEventRef::describe(ctx); + let def = StructDef::new( + "RadrootsComment", + "RadrootsComment", + span("crates/events/src/comment.rs", 8), + ) + .with_field(field( + "root", + "root", + event_ref, + "crates/events/src/comment.rs", + 9, + )) + .with_field(field( + "parent", + "parent", + RadrootsNostrEventRef::describe(ctx), + "crates/events/src/comment.rs", + 10, + )) + .with_field(field( + "content", + "content", + String::describe(ctx), + "crates/events/src/comment.rs", + 11, + )); + register(ctx, "RadrootsComment", TypeDef::Struct(def)) + } +} + +impl Dto for RadrootsReaction { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef::new( + "RadrootsReaction", + "RadrootsReaction", + span("crates/events/src/reaction.rs", 8), + ) + .with_field(field( + "root", + "root", + RadrootsNostrEventRef::describe(ctx), + "crates/events/src/reaction.rs", + 9, + )) + .with_field(field( + "content", + "content", + String::describe(ctx), + "crates/events/src/reaction.rs", + 10, + )); + register(ctx, "RadrootsReaction", TypeDef::Struct(def)) + } +} + +impl Dto for RadrootsPost { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef::new( + "RadrootsPost", + "RadrootsPost", + span("crates/events/src/post.rs", 11), + ) + .with_field(field( + "content", + "content", + String::describe(ctx), + "crates/events/src/post.rs", + 12, + )); + register(ctx, "RadrootsPost", TypeDef::Struct(def)) + } +} + +impl Dto for RadrootsListingParseError { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = EnumDef::new( + "RadrootsListingParseError", + "RadrootsTradeListingParseError", + EnumRepr::External, + span("crates/events/src/order.rs", 26), + ) + .with_variant(VariantDef::new( + "InvalidKind", + "InvalidKind", + VariantShape::Newtype(u32::describe(ctx)), + span("crates/events/src/order.rs", 27), + )) + .with_variant(VariantDef::new( + "MissingTag", + "MissingTag", + VariantShape::Newtype(String::describe(ctx)), + span("crates/events/src/order.rs", 28), + )) + .with_variant(VariantDef::new( + "InvalidTag", + "InvalidTag", + VariantShape::Newtype(String::describe(ctx)), + span("crates/events/src/order.rs", 29), + )) + .with_variant(VariantDef::new( + "InvalidNumber", + "InvalidNumber", + VariantShape::Newtype(String::describe(ctx)), + span("crates/events/src/order.rs", 30), + )) + .with_variant(VariantDef::new( + "InvalidUnit", + "InvalidUnit", + VariantShape::Unit, + span("crates/events/src/order.rs", 31), + )) + .with_variant(VariantDef::new( + "InvalidCurrency", + "InvalidCurrency", + VariantShape::Unit, + span("crates/events/src/order.rs", 32), + )) + .with_variant(VariantDef::new( + "InvalidJson", + "InvalidJson", + VariantShape::Newtype(String::describe(ctx)), + span("crates/events/src/order.rs", 33), + )) + .with_variant(VariantDef::new( + "InvalidDiscount", + "InvalidDiscount", + VariantShape::Newtype(String::describe(ctx)), + span("crates/events/src/order.rs", 34), + )); + register(ctx, "RadrootsListingParseError", TypeDef::Enum(def)) + } +} + +impl Dto for RadrootsTradeValidationListingError { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let parse_error = RadrootsListingParseError::describe(ctx); + let def = EnumDef::new( + "RadrootsTradeValidationListingError", + "RadrootsTradeListingValidationError", + EnumRepr::Adjacent { + tag: "kind".to_owned(), + content: "amount".to_owned(), + }, + span("crates/events/src/trade_validation.rs", 14), + ) + .with_variant(VariantDef::new( + "InvalidKind", + "invalid_kind", + VariantShape::Struct(vec![field( + "kind", + "kind", + u32::describe(ctx), + "crates/events/src/trade_validation.rs", + 15, + )]), + span("crates/events/src/trade_validation.rs", 15), + )) + .with_variant(unit_variant( + "MissingListingId", + "missing_listing_id", + "crates/events/src/trade_validation.rs", + 16, + )) + .with_variant(VariantDef::new( + "ListingEventNotFound", + "listing_event_not_found", + VariantShape::Struct(vec![field( + "listing_addr", + "listing_addr", + String::describe(ctx), + "crates/events/src/trade_validation.rs", + 17, + )]), + span("crates/events/src/trade_validation.rs", 17), + )) + .with_variant(VariantDef::new( + "ListingEventFetchFailed", + "listing_event_fetch_failed", + VariantShape::Struct(vec![field( + "listing_addr", + "listing_addr", + String::describe(ctx), + "crates/events/src/trade_validation.rs", + 18, + )]), + span("crates/events/src/trade_validation.rs", 18), + )) + .with_variant(VariantDef::new( + "ParseError", + "parse_error", + VariantShape::Struct(vec![field( + "error", + "error", + parse_error, + "crates/events/src/trade_validation.rs", + 19, + )]), + span("crates/events/src/trade_validation.rs", 19), + )) + .with_variant(unit_variant( + "InvalidSeller", + "invalid_seller", + "crates/events/src/trade_validation.rs", + 20, + )) + .with_variant(unit_variant( + "MissingFarmProfile", + "missing_farm_profile", + "crates/events/src/trade_validation.rs", + 21, + )) + .with_variant(unit_variant( + "MissingFarmRecord", + "missing_farm_record", + "crates/events/src/trade_validation.rs", + 22, + )) + .with_variant(unit_variant( + "MissingTitle", + "missing_title", + "crates/events/src/trade_validation.rs", + 23, + )) + .with_variant(unit_variant( + "MissingDescription", + "missing_description", + "crates/events/src/trade_validation.rs", + 24, + )) + .with_variant(unit_variant( + "MissingProductType", + "missing_product_type", + "crates/events/src/trade_validation.rs", + 25, + )) + .with_variant(unit_variant( + "MissingBins", + "missing_bins", + "crates/events/src/trade_validation.rs", + 26, + )) + .with_variant(unit_variant( + "MissingPrimaryBin", + "missing_primary_bin", + "crates/events/src/trade_validation.rs", + 27, + )) + .with_variant(unit_variant( + "InvalidBin", + "invalid_bin", + "crates/events/src/trade_validation.rs", + 28, + )) + .with_variant(unit_variant( + "MissingPrice", + "missing_price", + "crates/events/src/trade_validation.rs", + 29, + )) + .with_variant(unit_variant( + "InvalidPrice", + "invalid_price", + "crates/events/src/trade_validation.rs", + 30, + )) + .with_variant(unit_variant( + "MissingInventory", + "missing_inventory", + "crates/events/src/trade_validation.rs", + 31, + )) + .with_variant(unit_variant( + "InvalidInventory", + "invalid_inventory", + "crates/events/src/trade_validation.rs", + 32, + )) + .with_variant(unit_variant( + "MissingAvailability", + "missing_availability", + "crates/events/src/trade_validation.rs", + 33, + )) + .with_variant(unit_variant( + "MissingLocation", + "missing_location", + "crates/events/src/trade_validation.rs", + 34, + )) + .with_variant(unit_variant( + "MissingDeliveryMethod", + "missing_delivery_method", + "crates/events/src/trade_validation.rs", + 35, + )); + register( + ctx, + "RadrootsTradeValidationListingError", + TypeDef::Enum(def), + ) + } +} + +impl Dto for RadrootsOrderEconomicItem { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef::new( + "RadrootsOrderEconomicItem", + "RadrootsTradeOrderEconomicItem", + span("crates/events/src/order_economics.rs", 70), + ) + .with_field(field( + "bin_id", + "bin_id", + RadrootsInventoryBinId::describe(ctx), + "crates/events/src/order_economics.rs", + 71, + )) + .with_field(field( + "bin_count", + "bin_count", + u32::describe(ctx), + "crates/events/src/order_economics.rs", + 72, + )) + .with_field(field( + "quantity_amount", + "quantity_amount", + core_decimal(ctx), + "crates/events/src/order_economics.rs", + 73, + )) + .with_field(field( + "quantity_unit", + "quantity_unit", + radroots_core::RadrootsCoreUnit::describe(ctx), + "crates/events/src/order_economics.rs", + 74, + )) + .with_field(field( + "unit_price_amount", + "unit_price_amount", + core_decimal(ctx), + "crates/events/src/order_economics.rs", + 75, + )) + .with_field(field( + "unit_price_currency", + "unit_price_currency", + core_currency(ctx), + "crates/events/src/order_economics.rs", + 76, + )) + .with_field(field( + "line_subtotal", + "line_subtotal", + radroots_core::RadrootsCoreMoney::describe(ctx), + "crates/events/src/order_economics.rs", + 77, + )); + register(ctx, "RadrootsOrderEconomicItem", TypeDef::Struct(def)) + } +} + +impl Dto for RadrootsOrderEconomics { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef::new( + "RadrootsOrderEconomics", + "RadrootsTradeOrderEconomics", + span("crates/events/src/order_economics.rs", 119), + ) + .with_field(field( + "quote_id", + "quote_id", + RadrootsOrderQuoteId::describe(ctx), + "crates/events/src/order_economics.rs", + 120, + )) + .with_field(field( + "quote_version", + "quote_version", + u32::describe(ctx), + "crates/events/src/order_economics.rs", + 121, + )) + .with_field(field( + "pricing_basis", + "pricing_basis", + RadrootsOrderPricingBasis::describe(ctx), + "crates/events/src/order_economics.rs", + 122, + )) + .with_field(field( + "currency", + "currency", + core_currency(ctx), + "crates/events/src/order_economics.rs", + 123, + )) + .with_field(field( + "items", + "items", + <Vec<RadrootsOrderEconomicItem> as Dto>::describe(ctx), + "crates/events/src/order_economics.rs", + 124, + )) + .with_field(field( + "discounts", + "discounts", + <Vec<RadrootsOrderEconomicLine> as Dto>::describe(ctx), + "crates/events/src/order_economics.rs", + 125, + )) + .with_field(field( + "adjustments", + "adjustments", + <Vec<RadrootsOrderEconomicLine> as Dto>::describe(ctx), + "crates/events/src/order_economics.rs", + 126, + )) + .with_field(field( + "subtotal", + "subtotal", + radroots_core::RadrootsCoreMoney::describe(ctx), + "crates/events/src/order_economics.rs", + 127, + )) + .with_field(field( + "discount_total", + "discount_total", + radroots_core::RadrootsCoreMoney::describe(ctx), + "crates/events/src/order_economics.rs", + 128, + )) + .with_field(field( + "adjustment_total", + "adjustment_total", + radroots_core::RadrootsCoreMoney::describe(ctx), + "crates/events/src/order_economics.rs", + 129, + )) + .with_field(field( + "total", + "total", + radroots_core::RadrootsCoreMoney::describe(ctx), + "crates/events/src/order_economics.rs", + 130, + )); + register(ctx, "RadrootsOrderEconomics", TypeDef::Struct(def)) + } +} + +impl Dto for RadrootsOrderRevisionOutcome { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = EnumDef::new( + "RadrootsOrderRevisionOutcome", + "RadrootsTradeOrderRevisionDecision", + EnumRepr::Internal { + tag: "decision".to_owned(), + }, + span("crates/events/src/order.rs", 221), + ) + .with_variant(VariantDef::new( + "Accepted", + "accepted", + VariantShape::Unit, + span("crates/events/src/order.rs", 222), + )) + .with_variant(VariantDef::new( + "Declined", + "declined", + VariantShape::Struct(vec![field( + "reason", + "reason", + String::describe(ctx), + "crates/events/src/order.rs", + 223, + )]), + span("crates/events/src/order.rs", 223), + )); + register(ctx, "RadrootsOrderRevisionOutcome", TypeDef::Enum(def)) + } +} + +impl Dto for RadrootsActiveTradeEnvelopeDto { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef { + generics: vec![GenericParam::new("T")], + ..StructDef::new( + "RadrootsActiveTradeEnvelopeDto", + "RadrootsActiveTradeEnvelope", + span("crates/events/src/order.rs", 408), + ) + } + .with_field(field( + "version", + "version", + u16::describe(ctx), + "crates/events/src/order.rs", + 409, + )) + .with_field(field( + "domain", + "domain", + RadrootsCommercialDomain::describe(ctx), + "crates/events/src/order.rs", + 410, + )) + .with_field(field( + "message_type", + "type", + RadrootsOrderEventType::describe(ctx), + "crates/events/src/order.rs", + 412, + )) + .with_field(field( + "order_id", + "order_id", + String::describe(ctx), + "crates/events/src/order.rs", + 413, + )) + .with_field(field( + "listing_addr", + "listing_addr", + String::describe(ctx), + "crates/events/src/order.rs", + 414, + )) + .with_field(field( + "payload", + "payload", + TypeRef::GenericParam("T".to_owned()), + "crates/events/src/order.rs", + 415, + )); + register(ctx, "RadrootsActiveTradeEnvelopeDto", TypeDef::Struct(def)) + } +} + +impl Dto for RadrootsTradeEnvelopeDto { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef { + generics: vec![GenericParam::new("T")], + ..StructDef::new( + "RadrootsTradeEnvelopeDto", + "RadrootsTradeEnvelope", + span("crates/events/src/order.rs", 408), + ) + } + .with_field(field( + "version", + "version", + u16::describe(ctx), + "crates/events/src/order.rs", + 409, + )) + .with_field(field( + "domain", + "domain", + RadrootsCommercialDomain::describe(ctx), + "crates/events/src/order.rs", + 410, + )) + .with_field(field( + "message_type", + "type", + RadrootsTradeMessageTypeDto::describe(ctx), + "crates/events/src/order.rs", + 412, + )) + .with_field(optional_nullable_field( + "order_id", + "order_id", + <Option<String> as Dto>::describe(ctx), + "crates/events/src/order.rs", + 413, + )) + .with_field(field( + "listing_addr", + "listing_addr", + String::describe(ctx), + "crates/events/src/order.rs", + 414, + )) + .with_field(field( + "payload", + "payload", + TypeRef::GenericParam("T".to_owned()), + "crates/events/src/order.rs", + 415, + )); + register(ctx, "RadrootsTradeEnvelopeDto", TypeDef::Struct(def)) + } +} + +impl Dto for RadrootsTradeMessageTypeDto { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = EnumDef::new( + "RadrootsTradeMessageTypeDto", + "RadrootsTradeMessageType", + EnumRepr::External, + span("crates/events/src/order.rs", 408), + ) + .with_variant(unit_variant( + "ListingValidateRequest", + "listing_validate_request", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "ListingValidateResult", + "listing_validate_result", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "OrderRequest", + "order_request", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "OrderResponse", + "order_response", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "OrderRevision", + "order_revision", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "OrderRevisionAccept", + "order_revision_accept", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "OrderRevisionDecline", + "order_revision_decline", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "Question", + "question", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "Answer", + "answer", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "DiscountRequest", + "discount_request", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "DiscountOffer", + "discount_offer", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "DiscountAccept", + "discount_accept", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "DiscountDecline", + "discount_decline", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "Cancel", + "cancel", + "crates/events/src/order.rs", + 408, + )); + register(ctx, "RadrootsTradeMessageTypeDto", TypeDef::Enum(def)) + } +} + +impl Dto for RadrootsTradeTransportLaneDto { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = EnumDef::new( + "RadrootsTradeTransportLaneDto", + "RadrootsTradeTransportLane", + EnumRepr::External, + span("crates/events/src/order.rs", 408), + ) + .with_variant(unit_variant( + "Service", + "service", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "Public", + "public", + "crates/events/src/order.rs", + 408, + )); + register(ctx, "RadrootsTradeTransportLaneDto", TypeDef::Enum(def)) + } +} + +impl Dto for RadrootsTradeOrderStatusDto { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = EnumDef::new( + "RadrootsTradeOrderStatusDto", + "RadrootsTradeOrderStatus", + EnumRepr::External, + span("crates/events/src/order.rs", 408), + ) + .with_variant(unit_variant( + "Draft", + "draft", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "Validated", + "validated", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "Requested", + "requested", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "Questioned", + "questioned", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "Revised", + "revised", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "Accepted", + "accepted", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "Declined", + "declined", + "crates/events/src/order.rs", + 408, + )) + .with_variant(unit_variant( + "Cancelled", + "cancelled", + "crates/events/src/order.rs", + 408, + )); + register(ctx, "RadrootsTradeOrderStatusDto", TypeDef::Enum(def)) + } +} + +impl Dto for RadrootsTradeQuestionDto { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef::new( + "RadrootsTradeQuestionDto", + "RadrootsTradeQuestion", + span("crates/events/src/order.rs", 408), + ) + .with_field(field( + "question_id", + "question_id", + String::describe(ctx), + "crates/events/src/order.rs", + 408, + )); + register(ctx, "RadrootsTradeQuestionDto", TypeDef::Struct(def)) + } +} + +impl Dto for RadrootsTradeAnswerDto { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef::new( + "RadrootsTradeAnswerDto", + "RadrootsTradeAnswer", + span("crates/events/src/order.rs", 408), + ) + .with_field(field( + "question_id", + "question_id", + String::describe(ctx), + "crates/events/src/order.rs", + 408, + )); + register(ctx, "RadrootsTradeAnswerDto", TypeDef::Struct(def)) + } +} + +impl Dto for RadrootsTradeDiscountRequestDto { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef::new( + "RadrootsTradeDiscountRequestDto", + "RadrootsTradeDiscountRequest", + span("crates/events/src/order.rs", 408), + ) + .with_field(field( + "discount_id", + "discount_id", + String::describe(ctx), + "crates/events/src/order.rs", + 408, + )) + .with_field(field( + "value", + "value", + RadrootsCoreDiscountValue::describe(ctx), + "crates/events/src/order.rs", + 408, + )); + register(ctx, "RadrootsTradeDiscountRequestDto", TypeDef::Struct(def)) + } +} + +impl Dto for RadrootsTradeDiscountOfferDto { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef::new( + "RadrootsTradeDiscountOfferDto", + "RadrootsTradeDiscountOffer", + span("crates/events/src/order.rs", 408), + ) + .with_field(field( + "discount_id", + "discount_id", + String::describe(ctx), + "crates/events/src/order.rs", + 408, + )) + .with_field(field( + "value", + "value", + RadrootsCoreDiscountValue::describe(ctx), + "crates/events/src/order.rs", + 408, + )); + register(ctx, "RadrootsTradeDiscountOfferDto", TypeDef::Struct(def)) + } +} + +impl Dto for RadrootsTradeDiscountDecisionDto { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = EnumDef::new( + "RadrootsTradeDiscountDecisionDto", + "RadrootsTradeDiscountDecision", + EnumRepr::Adjacent { + tag: "kind".to_owned(), + content: "amount".to_owned(), + }, + span("crates/events/src/order.rs", 408), + ) + .with_variant(VariantDef::new( + "Accept", + "accept", + VariantShape::Struct(vec![field( + "value", + "value", + RadrootsCoreDiscountValue::describe(ctx), + "crates/events/src/order.rs", + 408, + )]), + span("crates/events/src/order.rs", 408), + )) + .with_variant(VariantDef::new( + "Decline", + "decline", + VariantShape::Struct(vec![optional_nullable_field( + "reason", + "reason", + <Option<String> as Dto>::describe(ctx), + "crates/events/src/order.rs", + 408, + )]), + span("crates/events/src/order.rs", 408), + )); + register(ctx, "RadrootsTradeDiscountDecisionDto", TypeDef::Enum(def)) + } +} + +impl Dto for RadrootsTradeListingCancelDto { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef::new( + "RadrootsTradeListingCancelDto", + "RadrootsTradeListingCancel", + span("crates/events/src/order.rs", 408), + ) + .with_field(optional_nullable_field( + "reason", + "reason", + <Option<String> as Dto>::describe(ctx), + "crates/events/src/order.rs", + 408, + )); + register(ctx, "RadrootsTradeListingCancelDto", TypeDef::Struct(def)) + } +} + +impl Dto for RadrootsTradeOrderResponseDto { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + accepted_reason_struct( + ctx, + "RadrootsTradeOrderResponseDto", + "RadrootsTradeOrderResponse", + ) + } +} + +impl Dto for RadrootsTradeOrderRevisionResponseDto { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + accepted_reason_struct( + ctx, + "RadrootsTradeOrderRevisionResponseDto", + "RadrootsTradeOrderRevisionResponse", + ) + } +} + +impl Dto for RadrootsTradeOrderRevisionDto { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef::new( + "RadrootsTradeOrderRevisionDto", + "RadrootsTradeOrderRevision", + span("crates/events/src/order.rs", 408), + ) + .with_field(field( + "revision_id", + "revision_id", + String::describe(ctx), + "crates/events/src/order.rs", + 408, + )) + .with_field(field( + "changes", + "changes", + <Vec<RadrootsTradeOrderChangeDto> as Dto>::describe(ctx), + "crates/events/src/order.rs", + 408, + )); + register(ctx, "RadrootsTradeOrderRevisionDto", TypeDef::Struct(def)) + } +} + +impl Dto for RadrootsTradeOrderChangeDto { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = EnumDef::new( + "RadrootsTradeOrderChangeDto", + "RadrootsTradeOrderChange", + EnumRepr::Adjacent { + tag: "kind".to_owned(), + content: "amount".to_owned(), + }, + span("crates/events/src/order.rs", 408), + ) + .with_variant(VariantDef::new( + "BinCount", + "bin_count", + VariantShape::Struct(vec![ + field( + "item_index", + "item_index", + u32::describe(ctx), + "crates/events/src/order.rs", + 408, + ), + field( + "bin_count", + "bin_count", + u32::describe(ctx), + "crates/events/src/order.rs", + 408, + ), + ]), + span("crates/events/src/order.rs", 408), + )) + .with_variant(VariantDef::new( + "ItemAdd", + "item_add", + VariantShape::Struct(vec![field( + "item", + "item", + RadrootsOrderItem::describe(ctx), + "crates/events/src/order.rs", + 408, + )]), + span("crates/events/src/order.rs", 408), + )) + .with_variant(VariantDef::new( + "ItemRemove", + "item_remove", + VariantShape::Struct(vec![field( + "item_index", + "item_index", + u32::describe(ctx), + "crates/events/src/order.rs", + 408, + )]), + span("crates/events/src/order.rs", 408), + )); + register(ctx, "RadrootsTradeOrderChangeDto", TypeDef::Enum(def)) + } +} + +impl Dto for RadrootsTradeMessagePayloadDto { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = EnumDef::new( + "RadrootsTradeMessagePayloadDto", + "RadrootsTradeMessagePayload", + EnumRepr::Adjacent { + tag: "kind".to_owned(), + content: "amount".to_owned(), + }, + span("crates/events/src/order.rs", 408), + ) + .with_variant(newtype_variant( + "ListingValidateRequest", + "listing_validate_request", + RadrootsTradeValidationListingRequest::describe(ctx), + )) + .with_variant(newtype_variant( + "ListingValidateResult", + "listing_validate_result", + RadrootsTradeValidationListingResult::describe(ctx), + )) + .with_variant(newtype_variant( + "TradeOrderRequested", + "trade_order_requested", + RadrootsOrderRequest::describe(ctx), + )) + .with_variant(newtype_variant( + "OrderResponse", + "order_response", + RadrootsTradeOrderResponseDto::describe(ctx), + )) + .with_variant(newtype_variant( + "OrderRevision", + "order_revision", + RadrootsTradeOrderRevisionDto::describe(ctx), + )) + .with_variant(newtype_variant( + "OrderRevisionAccept", + "order_revision_accept", + RadrootsTradeOrderRevisionResponseDto::describe(ctx), + )) + .with_variant(newtype_variant( + "OrderRevisionDecline", + "order_revision_decline", + RadrootsTradeOrderRevisionResponseDto::describe(ctx), + )) + .with_variant(newtype_variant( + "Question", + "question", + RadrootsTradeQuestionDto::describe(ctx), + )) + .with_variant(newtype_variant( + "Answer", + "answer", + RadrootsTradeAnswerDto::describe(ctx), + )) + .with_variant(newtype_variant( + "DiscountRequest", + "discount_request", + RadrootsTradeDiscountRequestDto::describe(ctx), + )) + .with_variant(newtype_variant( + "DiscountOffer", + "discount_offer", + RadrootsTradeDiscountOfferDto::describe(ctx), + )) + .with_variant(newtype_variant( + "DiscountAccept", + "discount_accept", + RadrootsTradeDiscountDecisionDto::describe(ctx), + )) + .with_variant(newtype_variant( + "DiscountDecline", + "discount_decline", + RadrootsTradeDiscountDecisionDto::describe(ctx), + )) + .with_variant(newtype_variant( + "Cancel", + "cancel", + RadrootsTradeListingCancelDto::describe(ctx), + )); + register(ctx, "RadrootsTradeMessagePayloadDto", TypeDef::Enum(def)) + } +} + fn register(ctx: &mut DescribeCtx, rust_ident: &str, type_def: TypeDef) -> TypeRef { ctx.register_type(RustTypeId::new("radroots_events", rust_ident), type_def) } -fn nullable_field( +fn core_decimal(ctx: &mut DescribeCtx) -> TypeRef { + external_core_alias(ctx, "RadrootsCoreDecimal") +} + +fn core_currency(ctx: &mut DescribeCtx) -> TypeRef { + external_core_alias(ctx, "RadrootsCoreCurrency") +} + +fn external_core_alias(ctx: &mut DescribeCtx, rust_ident: &str) -> TypeRef { + ctx.register_type( + RustTypeId::new("radroots_core", rust_ident), + TypeDef::Struct(StructDef::new( + rust_ident, + rust_ident, + span("crates/core/src/dto.rs", 1), + )), + ) +} + +fn accepted_reason_struct(ctx: &mut DescribeCtx, rust_ident: &str, export_name: &str) -> TypeRef { + let def = StructDef::new( + rust_ident, + export_name, + span("crates/events/src/order.rs", 408), + ) + .with_field(field( + "accepted", + "accepted", + bool::describe(ctx), + "crates/events/src/order.rs", + 408, + )) + .with_field(optional_nullable_field( + "reason", + "reason", + <Option<String> as Dto>::describe(ctx), + "crates/events/src/order.rs", + 408, + )); + register(ctx, rust_ident, TypeDef::Struct(def)) +} + +fn unit_variant(rust_name: &str, wire_name: &str, file: &str, line: u32) -> VariantDef { + VariantDef::new(rust_name, wire_name, VariantShape::Unit, span(file, line)) +} + +fn newtype_variant(rust_name: &str, wire_name: &str, ty: TypeRef) -> VariantDef { + VariantDef::new( + rust_name, + wire_name, + VariantShape::Newtype(ty), + span("crates/events/src/order.rs", 408), + ) +} + +fn optional_nullable_field( rust_name: &str, wire_name: &str, ty: TypeRef, file: &str, line: u32, ) -> FieldDef { - field(rust_name, wire_name, ty, file, line).with_presence(FieldPresence::nullable_required()) + field(rust_name, wire_name, ty, file, line).with_presence(FieldPresence::optional_nullable()) } fn field(rust_name: &str, wire_name: &str, ty: TypeRef, file: &str, line: u32) -> FieldDef { @@ -324,4 +2076,41 @@ mod tests { .any(|def| matches!(def, TypeDef::Struct(def) if def.export_name == "RadrootsListingImageSize")) ); } + + #[test] + fn option_fields_are_optional_nullable() { + let registry = build_registry(dto_roots()); + + let product = registry + .types_by_id + .values() + .find_map(|def| match def { + TypeDef::Struct(def) if def.export_name == "RadrootsListingProduct" => Some(def), + _ => None, + }) + .expect("listing product descriptor exists"); + let summary = product + .fields + .iter() + .find(|field| field.rust_name.as_str() == "summary") + .expect("summary field exists"); + assert!(!summary.presence.required_on_deserialize); + assert!(summary.presence.nullable); + + let event_ref = registry + .types_by_id + .values() + .find_map(|def| match def { + TypeDef::Struct(def) if def.export_name == "RadrootsNostrEventRef" => Some(def), + _ => None, + }) + .expect("event ref descriptor exists"); + let d_tag = event_ref + .fields + .iter() + .find(|field| field.rust_name.as_str() == "d_tag") + .expect("d_tag field exists"); + assert!(!d_tag.presence.required_on_deserialize); + assert!(d_tag.presence.nullable); + } } diff --git a/crates/events/src/farm.rs b/crates/events/src/farm.rs @@ -1,6 +1,7 @@ #[cfg(not(feature = "std"))] use alloc::{string::String, vec::Vec}; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsFarm { @@ -14,6 +15,7 @@ pub struct RadrootsFarm { pub tags: Option<Vec<String>>, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, Default)] pub struct RadrootsFarmRef { @@ -21,6 +23,7 @@ pub struct RadrootsFarmRef { pub d_tag: String, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsGeoJsonPoint { @@ -29,6 +32,7 @@ pub struct RadrootsGeoJsonPoint { pub coordinates: [f64; 2], } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsGeoJsonPolygon { @@ -37,6 +41,7 @@ pub struct RadrootsGeoJsonPolygon { pub coordinates: Vec<Vec<[f64; 2]>>, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsGcsLocation { @@ -61,6 +66,7 @@ pub struct RadrootsGcsLocation { pub gc_country_name: Option<String>, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsFarmLocation { diff --git a/crates/events/src/follow.rs b/crates/events/src/follow.rs @@ -1,12 +1,14 @@ #[cfg(not(feature = "std"))] use alloc::{string::String, vec::Vec}; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsFollow { pub list: Vec<RadrootsFollowProfile>, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsFollowProfile { diff --git a/crates/events/src/geochat.rs b/crates/events/src/geochat.rs @@ -3,6 +3,7 @@ #[cfg(not(feature = "std"))] use alloc::string::String; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsGeoChat { diff --git a/crates/events/src/gift_wrap.rs b/crates/events/src/gift_wrap.rs @@ -3,6 +3,7 @@ #[cfg(not(feature = "std"))] use alloc::string::String; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsGiftWrap { @@ -11,6 +12,7 @@ pub struct RadrootsGiftWrap { pub expiration: Option<u32>, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsGiftWrapRecipient { diff --git a/crates/events/src/job.rs b/crates/events/src/job.rs @@ -1,27 +1,39 @@ #[cfg(not(feature = "std"))] use alloc::string::String; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] #[derive(Clone, Debug, PartialEq, Eq, Copy)] pub enum JobInputType { + #[cfg_attr(feature = "serde", serde(rename = "url"))] Url, + #[cfg_attr(feature = "serde", serde(rename = "event"))] Event, + #[cfg_attr(feature = "serde", serde(rename = "job"))] Job, + #[cfg_attr(feature = "serde", serde(rename = "text"))] Text, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] #[derive(Clone, Debug, PartialEq, Eq, Copy)] pub enum JobFeedbackStatus { + #[cfg_attr(feature = "serde", serde(rename = "payment_required"))] PaymentRequired, + #[cfg_attr(feature = "serde", serde(rename = "processing"))] Processing, + #[cfg_attr(feature = "serde", serde(rename = "error"))] Error, + #[cfg_attr(feature = "serde", serde(rename = "success"))] Success, + #[cfg_attr(feature = "serde", serde(rename = "partial"))] Partial, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct JobPaymentRequest { diff --git a/crates/events/src/job_feedback.rs b/crates/events/src/job_feedback.rs @@ -6,6 +6,7 @@ use crate::{ #[cfg(not(feature = "std"))] use alloc::string::String; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsJobFeedback { diff --git a/crates/events/src/job_request.rs b/crates/events/src/job_request.rs @@ -3,6 +3,7 @@ use crate::job::JobInputType; #[cfg(not(feature = "std"))] use alloc::{string::String, vec::Vec}; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsJobInput { @@ -12,6 +13,7 @@ pub struct RadrootsJobInput { pub marker: Option<String>, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsJobParam { @@ -19,6 +21,7 @@ pub struct RadrootsJobParam { pub value: String, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsJobRequest { diff --git a/crates/events/src/job_result.rs b/crates/events/src/job_result.rs @@ -3,6 +3,7 @@ use crate::{RadrootsNostrEventPtr, job::JobPaymentRequest, job_request::Radroots #[cfg(not(feature = "std"))] use alloc::{string::String, vec::Vec}; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsJobResult { diff --git a/crates/events/src/kinds.rs b/crates/events/src/kinds.rs @@ -89,8 +89,39 @@ pub const KIND_ORDER_DECISION: u32 = 3423; pub const KIND_ORDER_REVISION_PROPOSAL: u32 = 3424; pub const KIND_ORDER_REVISION_DECISION: u32 = 3425; pub const KIND_ORDER_CANCELLATION: u32 = 3432; +pub const KIND_TRADE_QUESTION: u32 = 3426; +pub const KIND_TRADE_ANSWER: u32 = 3427; +pub const KIND_TRADE_DISCOUNT_REQUEST: u32 = 3428; +pub const KIND_TRADE_DISCOUNT_OFFER: u32 = 3429; +pub const KIND_TRADE_DISCOUNT_ACCEPT: u32 = 3430; +pub const KIND_TRADE_FORBIDDEN_3431: u32 = 3431; +pub const KIND_TRADE_FULFILLMENT_UPDATE: u32 = 3433; +pub const KIND_TRADE_RECEIPT: u32 = 3434; pub const KIND_TRADE_VALIDATION_RECEIPT: u32 = 3440; +pub const KIND_TRADE_LISTING_VALIDATE_REQ: u32 = KIND_TRADE_LISTING_VALIDATION_REQUEST; +pub const KIND_TRADE_LISTING_VALIDATE_RES: u32 = KIND_TRADE_LISTING_VALIDATION_RESULT; +pub const KIND_WORKER_TRADE_TRANSITION_PROOF_REQ: u32 = KIND_TRADE_TRANSITION_PROOF_REQUEST; +pub const KIND_WORKER_TRADE_TRANSITION_PROOF_RES: u32 = KIND_TRADE_TRANSITION_PROOF_RESULT; +pub const KIND_TRADE_ORDER_REQUEST: u32 = KIND_ORDER_REQUEST; +pub const KIND_TRADE_ORDER_RESPONSE: u32 = KIND_ORDER_DECISION; +pub const KIND_TRADE_ORDER_DECISION: u32 = KIND_ORDER_DECISION; +pub const KIND_TRADE_ORDER_REVISION: u32 = KIND_ORDER_REVISION_PROPOSAL; +pub const KIND_TRADE_ORDER_REVISION_RESPONSE: u32 = KIND_ORDER_REVISION_DECISION; +pub const KIND_TRADE_CANCEL: u32 = KIND_ORDER_CANCELLATION; +pub const KIND_TRADE_LISTING_ORDER_REQ: u32 = KIND_ORDER_REQUEST; +pub const KIND_TRADE_LISTING_ORDER_RES: u32 = KIND_ORDER_DECISION; +pub const KIND_TRADE_LISTING_ORDER_REVISION_REQ: u32 = KIND_ORDER_REVISION_PROPOSAL; +pub const KIND_TRADE_LISTING_ORDER_REVISION_RES: u32 = KIND_ORDER_REVISION_DECISION; +pub const KIND_TRADE_LISTING_QUESTION_REQ: u32 = KIND_TRADE_QUESTION; +pub const KIND_TRADE_LISTING_ANSWER_RES: u32 = KIND_TRADE_ANSWER; +pub const KIND_TRADE_LISTING_DISCOUNT_REQ: u32 = KIND_TRADE_DISCOUNT_REQUEST; +pub const KIND_TRADE_LISTING_DISCOUNT_OFFER_RES: u32 = KIND_TRADE_DISCOUNT_OFFER; +pub const KIND_TRADE_LISTING_DISCOUNT_ACCEPT_REQ: u32 = KIND_TRADE_DISCOUNT_ACCEPT; +pub const KIND_TRADE_LISTING_CANCEL_REQ: u32 = KIND_ORDER_CANCELLATION; +pub const KIND_TRADE_LISTING_FULFILLMENT_UPDATE_REQ: u32 = KIND_TRADE_FULFILLMENT_UPDATE; +pub const KIND_TRADE_LISTING_RECEIPT_REQ: u32 = KIND_TRADE_RECEIPT; + pub const LISTING_EVENT_KINDS: [u32; 2] = [KIND_LISTING, KIND_LISTING_DRAFT]; pub const ORDER_EVENT_KINDS: [u32; 5] = [ diff --git a/crates/events/src/list.rs b/crates/events/src/list.rs @@ -1,6 +1,7 @@ #[cfg(not(feature = "std"))] use alloc::{string::String, vec::Vec}; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsList { @@ -8,6 +9,7 @@ pub struct RadrootsList { pub entries: Vec<RadrootsListEntry>, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsListEntry { diff --git a/crates/events/src/list_set.rs b/crates/events/src/list_set.rs @@ -3,6 +3,7 @@ use crate::list::RadrootsListEntry; #[cfg(not(feature = "std"))] use alloc::{string::String, vec::Vec}; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsListSet { diff --git a/crates/events/src/listing.rs b/crates/events/src/listing.rs @@ -109,6 +109,7 @@ pub struct RadrootsListingBin { pub display_price_unit: Option<RadrootsCoreUnit>, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsListingLocation { diff --git a/crates/events/src/message.rs b/crates/events/src/message.rs @@ -5,6 +5,7 @@ use crate::RadrootsNostrEventPtr; #[cfg(not(feature = "std"))] use alloc::{string::String, vec::Vec}; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsMessage { @@ -14,6 +15,7 @@ pub struct RadrootsMessage { pub subject: Option<String>, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsMessageRecipient { diff --git a/crates/events/src/message_file.rs b/crates/events/src/message_file.rs @@ -6,6 +6,7 @@ use crate::message::RadrootsMessageRecipient; #[cfg(not(feature = "std"))] use alloc::{string::String, vec::Vec}; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsMessageFile { @@ -19,6 +20,7 @@ pub struct RadrootsMessageFile { pub decryption_nonce: String, pub encrypted_hash: String, pub original_hash: Option<String>, + #[cfg_attr(feature = "dto-bindgen", dto(int_repr = "json_number_unsafe"))] pub size: Option<u64>, pub dimensions: Option<RadrootsMessageFileDimensions>, pub blurhash: Option<String>, @@ -26,6 +28,7 @@ pub struct RadrootsMessageFile { pub fallbacks: Vec<String>, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct RadrootsMessageFileDimensions { diff --git a/crates/events/src/order.rs b/crates/events/src/order.rs @@ -161,6 +161,8 @@ impl RadrootsOrderEconomics { } } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr(feature = "dto-bindgen", dto(ts(name = "RadrootsTradeOrderRequested")))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsOrderRequest { @@ -184,6 +186,11 @@ impl RadrootsOrderRequest { } } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr( + feature = "dto-bindgen", + dto(ts(name = "RadrootsTradeOrderRevisionProposed")) +)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsOrderRevisionProposal { @@ -232,6 +239,11 @@ impl RadrootsOrderRevisionOutcome { } } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr( + feature = "dto-bindgen", + dto(ts(name = "RadrootsTradeOrderRevisionDecisionEvent")) +)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsOrderRevisionDecision { @@ -258,6 +270,11 @@ impl RadrootsOrderRevisionDecision { } } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr( + feature = "dto-bindgen", + dto(ts(name = "RadrootsTradeInventoryCommitment")) +)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsOrderInventoryCommitment { @@ -265,16 +282,18 @@ pub struct RadrootsOrderInventoryCommitment { pub bin_count: u32, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr(feature = "dto-bindgen", dto(ts(name = "RadrootsTradeOrderDecision")))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "snake_case", tag = "decision"))] #[derive(Clone, Debug, PartialEq, Eq)] pub enum RadrootsOrderDecisionOutcome { + #[cfg_attr(feature = "serde", serde(rename = "accepted"))] Accepted { inventory_commitments: Vec<RadrootsOrderInventoryCommitment>, }, - Declined { - reason: String, - }, + #[cfg_attr(feature = "serde", serde(rename = "declined"))] + Declined { reason: String }, } impl RadrootsOrderDecisionOutcome { @@ -288,6 +307,11 @@ impl RadrootsOrderDecisionOutcome { } } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr( + feature = "dto-bindgen", + dto(ts(name = "RadrootsTradeOrderDecisionEvent")) +)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsOrderDecision { @@ -308,6 +332,8 @@ impl RadrootsOrderDecision { } } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr(feature = "dto-bindgen", dto(ts(name = "RadrootsTradeOrderCancelled")))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsOrderCancellation { @@ -328,6 +354,8 @@ impl RadrootsOrderCancellation { } } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr(feature = "dto-bindgen", dto(ts(name = "RadrootsTradeDomain")))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -336,6 +364,11 @@ pub enum RadrootsCommercialDomain { Listing, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr( + feature = "dto-bindgen", + dto(ts(name = "RadrootsActiveTradeMessageType")) +)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum RadrootsOrderEventType { diff --git a/crates/events/src/order_economics.rs b/crates/events/src/order_economics.rs @@ -9,6 +9,8 @@ use radroots_core::{ use crate::ids::{RadrootsInventoryBinId, RadrootsOrderQuoteId}; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr(feature = "dto-bindgen", dto(ts(name = "RadrootsTradeOrderItem")))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsOrderItem { @@ -16,35 +18,54 @@ pub struct RadrootsOrderItem { pub bin_count: u32, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr(feature = "dto-bindgen", dto(ts(name = "RadrootsTradePricingBasis")))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum RadrootsOrderPricingBasis { + #[cfg_attr(feature = "serde", serde(rename = "listing_event"))] ListingEvent, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr( + feature = "dto-bindgen", + dto(ts(name = "RadrootsTradeEconomicLineKind")) +)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum RadrootsOrderEconomicLineKind { + #[cfg_attr(feature = "serde", serde(rename = "listing_discount"))] ListingDiscount, + #[cfg_attr(feature = "serde", serde(rename = "basket_adjustment"))] BasketAdjustment, + #[cfg_attr(feature = "serde", serde(rename = "revision_adjustment"))] RevisionAdjustment, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr(feature = "dto-bindgen", dto(ts(name = "RadrootsTradeEconomicActor")))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum RadrootsOrderEconomicActor { + #[cfg_attr(feature = "serde", serde(rename = "buyer"))] Buyer, + #[cfg_attr(feature = "serde", serde(rename = "seller"))] Seller, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr(feature = "dto-bindgen", dto(ts(name = "RadrootsTradeEconomicEffect")))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum RadrootsOrderEconomicEffect { + #[cfg_attr(feature = "serde", serde(rename = "increase"))] Increase, + #[cfg_attr(feature = "serde", serde(rename = "decrease"))] Decrease, } @@ -60,6 +81,11 @@ pub struct RadrootsOrderEconomicItem { pub line_subtotal: RadrootsCoreMoney, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr( + feature = "dto-bindgen", + dto(ts(name = "RadrootsTradeOrderEconomicLine")) +)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsOrderEconomicLine { @@ -71,6 +97,11 @@ pub struct RadrootsOrderEconomicLine { pub reason: String, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr( + feature = "dto-bindgen", + dto(ts(name = "RadrootsTradeOrderEconomicTotals")) +)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsOrderEconomicTotals { diff --git a/crates/events/src/plot.rs b/crates/events/src/plot.rs @@ -3,6 +3,7 @@ use crate::farm::{RadrootsFarmRef, RadrootsGcsLocation}; #[cfg(not(feature = "std"))] use alloc::{string::String, vec::Vec}; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsPlotRef { @@ -10,6 +11,7 @@ pub struct RadrootsPlotRef { pub d_tag: String, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsPlot { @@ -21,6 +23,7 @@ pub struct RadrootsPlot { pub tags: Option<Vec<String>>, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsPlotLocation { diff --git a/crates/events/src/profile.rs b/crates/events/src/profile.rs @@ -8,14 +8,20 @@ pub const RADROOTS_PROFILE_TYPE_TAG_COOP: &str = "radroots:type:coop"; pub const RADROOTS_PROFILE_TYPE_TAG_ANY: &str = "radroots:type:any"; pub const RADROOTS_PROFILE_TYPE_TAG_RADROOTSD: &str = "radroots:type:radrootsd"; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] #[derive(Clone, Debug, PartialEq, Eq, Copy)] pub enum RadrootsProfileType { + #[cfg_attr(feature = "serde", serde(rename = "individual"))] Individual, + #[cfg_attr(feature = "serde", serde(rename = "farm"))] Farm, + #[cfg_attr(feature = "serde", serde(rename = "coop"))] Coop, + #[cfg_attr(feature = "serde", serde(rename = "any"))] Any, + #[cfg_attr(feature = "serde", serde(rename = "radrootsd"))] Radrootsd, } @@ -40,6 +46,7 @@ pub fn radroots_profile_type_from_tag_value(value: &str) -> Option<RadrootsProfi } } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsProfile { diff --git a/crates/events/src/relay_document.rs b/crates/events/src/relay_document.rs @@ -1,6 +1,7 @@ #[cfg(not(feature = "std"))] use alloc::{string::String, vec::Vec}; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsRelayDocument { diff --git a/crates/events/src/resource_area.rs b/crates/events/src/resource_area.rs @@ -5,6 +5,7 @@ use crate::farm::RadrootsGcsLocation; #[cfg(not(feature = "std"))] use alloc::{string::String, vec::Vec}; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsResourceArea { @@ -15,6 +16,7 @@ pub struct RadrootsResourceArea { pub tags: Option<Vec<String>>, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsResourceAreaRef { @@ -22,6 +24,7 @@ pub struct RadrootsResourceAreaRef { pub d_tag: String, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsResourceAreaLocation { diff --git a/crates/events/src/resource_cap.rs b/crates/events/src/resource_cap.rs @@ -7,6 +7,7 @@ use crate::resource_area::RadrootsResourceAreaRef; #[cfg(not(feature = "std"))] use alloc::{string::String, vec::Vec}; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsResourceHarvestProduct { diff --git a/crates/events/src/seal.rs b/crates/events/src/seal.rs @@ -3,6 +3,7 @@ #[cfg(not(feature = "std"))] use alloc::string::String; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug)] pub struct RadrootsSeal { diff --git a/crates/events/src/trade_validation.rs b/crates/events/src/trade_validation.rs @@ -70,12 +70,22 @@ impl core::fmt::Display for RadrootsTradeValidationListingError { #[cfg(feature = "std")] impl std::error::Error for RadrootsTradeValidationListingError {} +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr( + feature = "dto-bindgen", + dto(ts(name = "RadrootsTradeListingValidateRequest")) +)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsTradeValidationListingRequest { pub listing_event: Option<RadrootsNostrEventPtr>, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] +#[cfg_attr( + feature = "dto-bindgen", + dto(ts(name = "RadrootsTradeListingValidateResult")) +)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsTradeValidationListingResult { diff --git a/crates/events_indexed/Cargo.toml b/crates/events_indexed/Cargo.toml @@ -14,10 +14,13 @@ readme = "README" [features] default = ["serde"] +dto-bindgen = ["std", "serde", "dep:dto_bindgen", "dep:dto_bindgen_core"] serde = ["dep:serde"] std = [] [dependencies] +dto_bindgen = { workspace = true, optional = true } +dto_bindgen_core = { workspace = true, optional = true } serde = { workspace = true, default-features = false, features = [ "alloc", "derive", diff --git a/crates/events_indexed/src/dto.rs b/crates/events_indexed/src/dto.rs @@ -0,0 +1,198 @@ +use dto_bindgen_core::{ + BackendId, DescribeCtx, Dto, FieldDef, FieldPresence, IdentName, RootDescriptor, RustTypeId, + SourceSpan, StructDef, TargetFieldNames, TargetOverride, TypeDef, TypeRef, WireFieldNames, +}; + +use crate::{ + checkpoint::{RadrootsEventsIndexedIndexCheckpoint, RadrootsEventsIndexedShardCheckpoint}, + manifest::{RadrootsEventsIndexedManifest, RadrootsEventsIndexedShardMetadata}, + types::RadrootsEventsIndexedIdRange, +}; + +pub fn dto_roots() -> [RootDescriptor; 5] { + [ + RootDescriptor::new::<RadrootsEventsIndexedIdRange>(), + RootDescriptor::new::<RadrootsEventsIndexedShardMetadata>(), + RootDescriptor::new::<RadrootsEventsIndexedManifest>(), + RootDescriptor::new::<RadrootsEventsIndexedShardCheckpoint>(), + RootDescriptor::new::<RadrootsEventsIndexedIndexCheckpoint>(), + ] +} + +impl Dto for RadrootsEventsIndexedShardCheckpoint { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef::new( + "RadrootsEventsIndexedShardCheckpoint", + "RadrootsEventsIndexedShardCheckpoint", + span("crates/events_indexed/src/checkpoint.rs", 10), + ) + .with_field(field( + "shard_id", + "shard_id", + shard_id_ref(), + "crates/events_indexed/src/checkpoint.rs", + 11, + )) + .with_field(field( + "last_created_at", + "last_created_at", + u32::describe(ctx), + "crates/events_indexed/src/checkpoint.rs", + 16, + )) + .with_field(optional_nullable_field( + "last_event_id", + "last_event_id", + <Option<String> as Dto>::describe(ctx), + "crates/events_indexed/src/checkpoint.rs", + 17, + )) + .with_field(optional_nullable_field( + "cursor", + "cursor", + <Option<String> as Dto>::describe(ctx), + "crates/events_indexed/src/checkpoint.rs", + 18, + )); + register( + ctx, + "RadrootsEventsIndexedShardCheckpoint", + TypeDef::Struct(def), + ) + } +} + +impl Dto for RadrootsEventsIndexedIndexCheckpoint { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef::new( + "RadrootsEventsIndexedIndexCheckpoint", + "RadrootsEventsIndexedIndexCheckpoint", + span("crates/events_indexed/src/checkpoint.rs", 24), + ) + .with_field(field( + "generated_at", + "generated_at", + u32::describe(ctx), + "crates/events_indexed/src/checkpoint.rs", + 30, + )) + .with_field(field( + "shards", + "shards", + <Vec<RadrootsEventsIndexedShardCheckpoint> as Dto>::describe(ctx), + "crates/events_indexed/src/checkpoint.rs", + 31, + )); + register( + ctx, + "RadrootsEventsIndexedIndexCheckpoint", + TypeDef::Struct(def), + ) + } +} + +fn register(ctx: &mut DescribeCtx, rust_ident: &str, type_def: TypeDef) -> TypeRef { + ctx.register_type( + RustTypeId::new("radroots_events_indexed", rust_ident), + type_def, + ) +} + +fn shard_id_ref() -> TypeRef { + TypeRef::Override(TargetOverride::new( + BackendId::TypeScript, + "RadrootsEventsIndexedShardId", + )) +} + +fn optional_nullable_field( + rust_name: &str, + wire_name: &str, + ty: TypeRef, + file: &str, + line: u32, +) -> FieldDef { + field(rust_name, wire_name, ty, file, line).with_presence(FieldPresence::optional_nullable()) +} + +fn field(rust_name: &str, wire_name: &str, ty: TypeRef, file: &str, line: u32) -> FieldDef { + FieldDef::new( + IdentName::new(rust_name), + WireFieldNames::same(wire_name), + TargetFieldNames::new(wire_name, rust_name), + ty, + span(file, line), + ) +} + +fn span(file: &str, line: u32) -> SourceSpan { + SourceSpan::new(file, line, 1) +} + +#[cfg(test)] +mod tests { + use dto_bindgen_core::{FieldDef, Primitive, StructDef, TypeDef, TypeRef, build_registry}; + + use super::dto_roots; + + #[test] + fn indexed_descriptor_roots_build_registry() { + let registry = build_registry(dto_roots()); + + assert!(!registry.has_errors()); + assert_eq!(registry.roots.len(), dto_roots().len()); + assert!(registry.types_by_id.values().any( + |def| matches!(def, TypeDef::Struct(def) if def.export_name == "RadrootsEventsIndexedManifest") + )); + } + + #[test] + fn custom_epoch_second_fields_render_as_numbers() { + let registry = build_registry(dto_roots()); + let shard_checkpoint = find_struct(&registry, "RadrootsEventsIndexedShardCheckpoint"); + let index_checkpoint = find_struct(&registry, "RadrootsEventsIndexedIndexCheckpoint"); + + assert_eq!( + find_field(shard_checkpoint, "last_created_at").ty, + TypeRef::Primitive(Primitive::U32) + ); + assert_eq!( + find_field(index_checkpoint, "generated_at").ty, + TypeRef::Primitive(Primitive::U32) + ); + } + + #[test] + fn optional_checkpoint_fields_are_optional_nullable() { + let registry = build_registry(dto_roots()); + let checkpoint = find_struct(&registry, "RadrootsEventsIndexedShardCheckpoint"); + + for field_name in ["last_event_id", "cursor"] { + let field = find_field(checkpoint, field_name); + + assert!(field.presence.nullable); + assert!(!field.presence.required_on_deserialize); + } + } + + fn find_struct<'a>( + registry: &'a dto_bindgen_core::Registry, + export_name: &str, + ) -> &'a StructDef { + registry + .types_by_id + .values() + .find_map(|def| match def { + TypeDef::Struct(def) if def.export_name == export_name => Some(def), + _ => None, + }) + .expect("descriptor struct") + } + + fn find_field<'a>(def: &'a StructDef, typescript_name: &str) -> &'a FieldDef { + def.fields + .iter() + .find(|field| field.target.typescript == typescript_name) + .expect("descriptor field") + } +} diff --git a/crates/events_indexed/src/lib.rs b/crates/events_indexed/src/lib.rs @@ -3,6 +3,8 @@ extern crate alloc; pub mod checkpoint; +#[cfg(feature = "dto-bindgen")] +pub mod dto; pub mod manifest; pub mod serde_ext; pub mod types; diff --git a/crates/events_indexed/src/manifest.rs b/crates/events_indexed/src/manifest.rs @@ -3,6 +3,7 @@ use alloc::{string::String, vec::Vec}; use core::fmt; +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsEventsIndexedShardMetadata { @@ -15,6 +16,7 @@ pub struct RadrootsEventsIndexedShardMetadata { pub sha256: String, } +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsEventsIndexedManifest { diff --git a/crates/events_indexed/src/types.rs b/crates/events_indexed/src/types.rs @@ -5,6 +5,7 @@ use alloc::string::String; #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct RadrootsEventsIndexedShardId(pub String); +#[cfg_attr(feature = "dto-bindgen", derive(dto_bindgen::Dto))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsEventsIndexedIdRange { diff --git a/crates/replica_db_schema/Cargo.toml b/crates/replica_db_schema/Cargo.toml @@ -17,8 +17,10 @@ crate-type = ["rlib"] [features] default = [] +dto-bindgen = ["dep:dto_bindgen_core"] [dependencies] +dto_bindgen_core = { workspace = true, optional = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } radroots_types = { workspace = true } diff --git a/crates/replica_db_schema/src/dto.rs b/crates/replica_db_schema/src/dto.rs @@ -0,0 +1,2204 @@ +use dto_bindgen_core::{ + BackendId, DefaultKind, EnumDef, EnumRepr, FieldDef, FieldPresence, IdentName, Registry, + RustTypeId, SerializePresence, SourceSpan, StructDef, TargetFieldNames, TargetOverride, + TypeDef, TypeRef, VariantDef, VariantShape, WireFieldNames, +}; + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +enum TypeSpec { + Object { + name: &'static str, + fields: &'static [FieldSpec], + }, + Union { + name: &'static str, + variants: &'static [VariantSpec], + }, + Alias { + name: &'static str, + target: &'static str, + }, +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +enum VariantSpec { + Object(&'static [FieldSpec]), + Ref(&'static str), +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +struct FieldSpec { + name: &'static str, + target: &'static str, + optional: bool, + nullable: bool, +} + +impl FieldSpec { + const fn required(name: &'static str, target: &'static str) -> Self { + Self { + name, + target, + optional: false, + nullable: false, + } + } + + const fn nullable(name: &'static str, target: &'static str) -> Self { + Self { + name, + target, + optional: false, + nullable: true, + } + } + + const fn optional(name: &'static str, target: &'static str) -> Self { + Self { + name, + target, + optional: true, + nullable: false, + } + } + + const fn optional_nullable(name: &'static str, target: &'static str) -> Self { + Self { + name, + target, + optional: true, + nullable: true, + } + } +} + +pub fn dto_registry() -> Registry { + let mut registry = Registry::new(); + for spec in TYPE_SPECS { + let name = spec.name(); + let type_id = registry.register_type( + RustTypeId::new(env!("CARGO_PKG_NAME"), name), + spec.type_def(), + ); + registry.mark_root(type_id); + } + registry +} + +pub fn type_inventory() -> Vec<&'static str> { + TYPE_SPECS.iter().map(TypeSpec::name).collect() +} + +impl TypeSpec { + fn name(&self) -> &'static str { + match self { + Self::Object { name, .. } | Self::Union { name, .. } | Self::Alias { name, .. } => name, + } + } + + fn type_def(&self) -> TypeDef { + match self { + Self::Object { name, fields } => TypeDef::Struct(object_def(name, fields)), + Self::Union { name, variants } => TypeDef::Enum(union_def(name, variants)), + Self::Alias { name, target } => TypeDef::Enum(alias_def(name, target)), + } + } +} + +fn object_def(name: &str, fields: &[FieldSpec]) -> StructDef { + let mut def = StructDef::new(name, name, source_span()); + for field in fields { + def = def.with_field(field_def(field)); + } + def +} + +fn union_def(name: &str, variants: &[VariantSpec]) -> EnumDef { + let mut def = EnumDef::new(name, name, EnumRepr::Untagged, source_span()); + for (index, variant) in variants.iter().enumerate() { + def = def.with_variant(match variant { + VariantSpec::Object(fields) => VariantDef::new( + format!("Variant{index}"), + format!("variant{index}"), + VariantShape::Struct(fields.iter().map(field_def).collect()), + source_span(), + ), + VariantSpec::Ref(target) => VariantDef::new( + format!("Variant{index}"), + format!("variant{index}"), + VariantShape::Newtype(ts_ref(target)), + source_span(), + ), + }); + } + def +} + +fn alias_def(name: &str, target: &str) -> EnumDef { + EnumDef::new(name, name, EnumRepr::Untagged, source_span()).with_variant(VariantDef::new( + "Alias", + "alias", + VariantShape::Newtype(ts_ref(target)), + source_span(), + )) +} + +fn field_def(field: &FieldSpec) -> FieldDef { + FieldDef::new( + IdentName::new(field.name), + WireFieldNames::same(field.name), + TargetFieldNames::new(field.name, field.name), + ts_ref(field.target), + source_span(), + ) + .with_presence(field_presence(field.optional, field.nullable)) +} + +fn field_presence(optional: bool, nullable: bool) -> FieldPresence { + match (optional, nullable) { + (false, false) => FieldPresence::required(), + (false, true) => FieldPresence::nullable_required(), + (true, true) => FieldPresence::optional_nullable(), + (true, false) => FieldPresence { + nullable: false, + required_on_deserialize: false, + default: Some(DefaultKind::NoneValue), + serialize_presence: SerializePresence::Always, + }, + } +} + +fn ts_ref(target: &str) -> TypeRef { + TypeRef::Override(TargetOverride::new(BackendId::TypeScript, target)) +} + +fn source_span() -> SourceSpan { + SourceSpan::new(file!(), line!(), column!()) +} + +const TYPE_SPECS: &[TypeSpec] = &[ + TypeSpec::Object { + name: "Farm", + fields: &[ + FieldSpec::required("id", "string"), + FieldSpec::required("created_at", "string"), + FieldSpec::required("updated_at", "string"), + FieldSpec::required("d_tag", "string"), + FieldSpec::required("pubkey", "string"), + FieldSpec::required("name", "string"), + FieldSpec::nullable("about", "string"), + FieldSpec::nullable("website", "string"), + FieldSpec::nullable("picture", "string"), + FieldSpec::nullable("banner", "string"), + FieldSpec::nullable("location_primary", "string"), + FieldSpec::nullable("location_city", "string"), + FieldSpec::nullable("location_region", "string"), + FieldSpec::nullable("location_country", "string"), + ], + }, + TypeSpec::Object { + name: "FarmGcsLocation", + fields: &[ + FieldSpec::required("id", "string"), + FieldSpec::required("created_at", "string"), + FieldSpec::required("updated_at", "string"), + FieldSpec::required("farm_id", "string"), + FieldSpec::required("gcs_location_id", "string"), + FieldSpec::required("role", "string"), + ], + }, + TypeSpec::Union { + name: "FarmGcsLocationQueryBindValues", + variants: &[ + VariantSpec::Object(&[FieldSpec::required("id", "string")]), + VariantSpec::Object(&[FieldSpec::required("farm_id", "string")]), + VariantSpec::Object(&[FieldSpec::required("gcs_location_id", "string")]), + ], + }, + TypeSpec::Object { + name: "FarmMember", + fields: &[ + FieldSpec::required("id", "string"), + FieldSpec::required("created_at", "string"), + FieldSpec::required("updated_at", "string"), + FieldSpec::required("farm_id", "string"), + FieldSpec::required("member_pubkey", "string"), + FieldSpec::required("role", "string"), + ], + }, + TypeSpec::Object { + name: "FarmMemberClaim", + fields: &[ + FieldSpec::required("id", "string"), + FieldSpec::required("created_at", "string"), + FieldSpec::required("updated_at", "string"), + FieldSpec::required("member_pubkey", "string"), + FieldSpec::required("farm_pubkey", "string"), + ], + }, + TypeSpec::Union { + name: "FarmMemberClaimQueryBindValues", + variants: &[ + VariantSpec::Object(&[FieldSpec::required("id", "string")]), + VariantSpec::Object(&[FieldSpec::required("member_pubkey", "string")]), + VariantSpec::Object(&[FieldSpec::required("farm_pubkey", "string")]), + ], + }, + TypeSpec::Union { + name: "FarmMemberQueryBindValues", + variants: &[ + VariantSpec::Object(&[FieldSpec::required("id", "string")]), + VariantSpec::Object(&[FieldSpec::required("farm_id", "string")]), + VariantSpec::Object(&[FieldSpec::required("member_pubkey", "string")]), + ], + }, + TypeSpec::Union { + name: "FarmQueryBindValues", + variants: &[ + VariantSpec::Object(&[FieldSpec::required("id", "string")]), + VariantSpec::Object(&[FieldSpec::required("d_tag", "string")]), + VariantSpec::Object(&[FieldSpec::required("pubkey", "string")]), + ], + }, + TypeSpec::Object { + name: "FarmTag", + fields: &[ + FieldSpec::required("id", "string"), + FieldSpec::required("created_at", "string"), + FieldSpec::required("updated_at", "string"), + FieldSpec::required("farm_id", "string"), + FieldSpec::required("tag", "string"), + ], + }, + TypeSpec::Union { + name: "FarmTagQueryBindValues", + variants: &[ + VariantSpec::Object(&[FieldSpec::required("id", "string")]), + VariantSpec::Object(&[FieldSpec::required("farm_id", "string")]), + VariantSpec::Object(&[FieldSpec::required("tag", "string")]), + ], + }, + TypeSpec::Object { + name: "GcsLocation", + fields: &[ + FieldSpec::required("id", "string"), + FieldSpec::required("created_at", "string"), + FieldSpec::required("updated_at", "string"), + FieldSpec::required("d_tag", "string"), + FieldSpec::required("lat", "number"), + FieldSpec::required("lng", "number"), + FieldSpec::required("geohash", "string"), + FieldSpec::required("point", "string"), + FieldSpec::required("polygon", "string"), + FieldSpec::nullable("accuracy", "number"), + FieldSpec::nullable("altitude", "number"), + FieldSpec::nullable("tag_0", "string"), + FieldSpec::nullable("label", "string"), + FieldSpec::nullable("area", "number"), + FieldSpec::nullable("elevation", "number"), + FieldSpec::nullable("soil", "string"), + FieldSpec::nullable("climate", "string"), + FieldSpec::nullable("gc_id", "string"), + FieldSpec::nullable("gc_name", "string"), + FieldSpec::nullable("gc_admin1_id", "string"), + FieldSpec::nullable("gc_admin1_name", "string"), + FieldSpec::nullable("gc_country_id", "string"), + FieldSpec::nullable("gc_country_name", "string"), + ], + }, + TypeSpec::Object { + name: "GcsLocationFarmArgs", + fields: &[FieldSpec::required("id", "string")], + }, + TypeSpec::Union { + name: "GcsLocationFindManyRel", + variants: &[ + VariantSpec::Object(&[FieldSpec::required( + "on_trade_product", + "GcsLocationTradeProductArgs", + )]), + VariantSpec::Object(&[FieldSpec::required( + "off_trade_product", + "GcsLocationTradeProductArgs", + )]), + VariantSpec::Object(&[FieldSpec::required("on_farm", "GcsLocationFarmArgs")]), + VariantSpec::Object(&[FieldSpec::required("off_farm", "GcsLocationFarmArgs")]), + VariantSpec::Object(&[FieldSpec::required("on_plot", "GcsLocationPlotArgs")]), + VariantSpec::Object(&[FieldSpec::required("off_plot", "GcsLocationPlotArgs")]), + ], + }, + TypeSpec::Object { + name: "GcsLocationPlotArgs", + fields: &[FieldSpec::required("id", "string")], + }, + TypeSpec::Union { + name: "GcsLocationQueryBindValues", + variants: &[ + VariantSpec::Object(&[FieldSpec::required("id", "string")]), + VariantSpec::Object(&[FieldSpec::required("d_tag", "string")]), + VariantSpec::Object(&[FieldSpec::required("geohash", "string")]), + ], + }, + TypeSpec::Object { + name: "GcsLocationTradeProductArgs", + fields: &[FieldSpec::required("id", "string")], + }, + TypeSpec::Alias { + name: "IFarmCreate", + target: "IFarmFields", + }, + TypeSpec::Alias { + name: "IFarmCreateResolve", + target: "IResult<Farm>", + }, + TypeSpec::Alias { + name: "IFarmDelete", + target: "IFarmFindOne", + }, + TypeSpec::Alias { + name: "IFarmDeleteResolve", + target: "IResult<string>", + }, + TypeSpec::Object { + name: "IFarmFields", + fields: &[ + FieldSpec::required("d_tag", "string"), + FieldSpec::required("pubkey", "string"), + FieldSpec::required("name", "string"), + FieldSpec::optional_nullable("about", "string"), + FieldSpec::optional_nullable("website", "string"), + FieldSpec::optional_nullable("picture", "string"), + FieldSpec::optional_nullable("banner", "string"), + FieldSpec::optional_nullable("location_primary", "string"), + FieldSpec::optional_nullable("location_city", "string"), + FieldSpec::optional_nullable("location_region", "string"), + FieldSpec::optional_nullable("location_country", "string"), + ], + }, + TypeSpec::Object { + name: "IFarmFieldsFilter", + fields: &[ + FieldSpec::optional("id", "string"), + FieldSpec::optional("created_at", "string"), + FieldSpec::optional("updated_at", "string"), + FieldSpec::optional("d_tag", "string"), + FieldSpec::optional("pubkey", "string"), + FieldSpec::optional("name", "string"), + FieldSpec::optional("about", "string"), + FieldSpec::optional("website", "string"), + FieldSpec::optional("picture", "string"), + FieldSpec::optional("banner", "string"), + FieldSpec::optional("location_primary", "string"), + FieldSpec::optional("location_city", "string"), + FieldSpec::optional("location_region", "string"), + FieldSpec::optional("location_country", "string"), + ], + }, + TypeSpec::Object { + name: "IFarmFieldsPartial", + fields: &[ + FieldSpec::optional_nullable("d_tag", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("pubkey", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("name", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("about", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("website", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("picture", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("banner", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("location_primary", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("location_city", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("location_region", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("location_country", "ReplicaDbJsonValue"), + ], + }, + TypeSpec::Alias { + name: "IFarmFindMany", + target: "IFarmFindManyArgs", + }, + TypeSpec::Object { + name: "IFarmFindManyArgs", + fields: &[FieldSpec::nullable("filter", "IFarmFieldsFilter")], + }, + TypeSpec::Alias { + name: "IFarmFindManyResolve", + target: "IResultList<Farm>", + }, + TypeSpec::Union { + name: "IFarmFindOne", + variants: &[VariantSpec::Ref("IFarmFindOneArgs")], + }, + TypeSpec::Object { + name: "IFarmFindOneArgs", + fields: &[FieldSpec::required("on", "FarmQueryBindValues")], + }, + TypeSpec::Alias { + name: "IFarmFindOneResolve", + target: "IResult<Farm | null>", + }, + TypeSpec::Alias { + name: "IFarmGcsLocationCreate", + target: "IFarmGcsLocationFields", + }, + TypeSpec::Alias { + name: "IFarmGcsLocationCreateResolve", + target: "IResult<FarmGcsLocation>", + }, + TypeSpec::Alias { + name: "IFarmGcsLocationDelete", + target: "IFarmGcsLocationFindOne", + }, + TypeSpec::Alias { + name: "IFarmGcsLocationDeleteResolve", + target: "IResult<string>", + }, + TypeSpec::Object { + name: "IFarmGcsLocationFields", + fields: &[ + FieldSpec::required("farm_id", "string"), + FieldSpec::required("gcs_location_id", "string"), + FieldSpec::required("role", "string"), + ], + }, + TypeSpec::Object { + name: "IFarmGcsLocationFieldsFilter", + fields: &[ + FieldSpec::optional("id", "string"), + FieldSpec::optional("created_at", "string"), + FieldSpec::optional("updated_at", "string"), + FieldSpec::optional("farm_id", "string"), + FieldSpec::optional("gcs_location_id", "string"), + FieldSpec::optional("role", "string"), + ], + }, + TypeSpec::Object { + name: "IFarmGcsLocationFieldsPartial", + fields: &[ + FieldSpec::optional_nullable("farm_id", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("gcs_location_id", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("role", "ReplicaDbJsonValue"), + ], + }, + TypeSpec::Alias { + name: "IFarmGcsLocationFindMany", + target: "IFarmGcsLocationFindManyArgs", + }, + TypeSpec::Object { + name: "IFarmGcsLocationFindManyArgs", + fields: &[FieldSpec::nullable( + "filter", + "IFarmGcsLocationFieldsFilter", + )], + }, + TypeSpec::Alias { + name: "IFarmGcsLocationFindManyResolve", + target: "IResultList<FarmGcsLocation>", + }, + TypeSpec::Union { + name: "IFarmGcsLocationFindOne", + variants: &[VariantSpec::Ref("IFarmGcsLocationFindOneArgs")], + }, + TypeSpec::Object { + name: "IFarmGcsLocationFindOneArgs", + fields: &[FieldSpec::required("on", "FarmGcsLocationQueryBindValues")], + }, + TypeSpec::Alias { + name: "IFarmGcsLocationFindOneResolve", + target: "IResult<FarmGcsLocation | null>", + }, + TypeSpec::Alias { + name: "IFarmGcsLocationUpdate", + target: "IFarmGcsLocationUpdateArgs", + }, + TypeSpec::Object { + name: "IFarmGcsLocationUpdateArgs", + fields: &[ + FieldSpec::required("on", "FarmGcsLocationQueryBindValues"), + FieldSpec::required("fields", "IFarmGcsLocationFieldsPartial"), + ], + }, + TypeSpec::Alias { + name: "IFarmGcsLocationUpdateResolve", + target: "IResult<FarmGcsLocation>", + }, + TypeSpec::Alias { + name: "IFarmMemberClaimCreate", + target: "IFarmMemberClaimFields", + }, + TypeSpec::Alias { + name: "IFarmMemberClaimCreateResolve", + target: "IResult<FarmMemberClaim>", + }, + TypeSpec::Alias { + name: "IFarmMemberClaimDelete", + target: "IFarmMemberClaimFindOne", + }, + TypeSpec::Alias { + name: "IFarmMemberClaimDeleteResolve", + target: "IResult<string>", + }, + TypeSpec::Object { + name: "IFarmMemberClaimFields", + fields: &[ + FieldSpec::required("member_pubkey", "string"), + FieldSpec::required("farm_pubkey", "string"), + ], + }, + TypeSpec::Object { + name: "IFarmMemberClaimFieldsFilter", + fields: &[ + FieldSpec::optional("id", "string"), + FieldSpec::optional("created_at", "string"), + FieldSpec::optional("updated_at", "string"), + FieldSpec::optional("member_pubkey", "string"), + FieldSpec::optional("farm_pubkey", "string"), + ], + }, + TypeSpec::Object { + name: "IFarmMemberClaimFieldsPartial", + fields: &[ + FieldSpec::optional_nullable("member_pubkey", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("farm_pubkey", "ReplicaDbJsonValue"), + ], + }, + TypeSpec::Alias { + name: "IFarmMemberClaimFindMany", + target: "IFarmMemberClaimFindManyArgs", + }, + TypeSpec::Object { + name: "IFarmMemberClaimFindManyArgs", + fields: &[FieldSpec::nullable( + "filter", + "IFarmMemberClaimFieldsFilter", + )], + }, + TypeSpec::Alias { + name: "IFarmMemberClaimFindManyResolve", + target: "IResultList<FarmMemberClaim>", + }, + TypeSpec::Union { + name: "IFarmMemberClaimFindOne", + variants: &[VariantSpec::Ref("IFarmMemberClaimFindOneArgs")], + }, + TypeSpec::Object { + name: "IFarmMemberClaimFindOneArgs", + fields: &[FieldSpec::required("on", "FarmMemberClaimQueryBindValues")], + }, + TypeSpec::Alias { + name: "IFarmMemberClaimFindOneResolve", + target: "IResult<FarmMemberClaim | null>", + }, + TypeSpec::Alias { + name: "IFarmMemberClaimUpdate", + target: "IFarmMemberClaimUpdateArgs", + }, + TypeSpec::Object { + name: "IFarmMemberClaimUpdateArgs", + fields: &[ + FieldSpec::required("on", "FarmMemberClaimQueryBindValues"), + FieldSpec::required("fields", "IFarmMemberClaimFieldsPartial"), + ], + }, + TypeSpec::Alias { + name: "IFarmMemberClaimUpdateResolve", + target: "IResult<FarmMemberClaim>", + }, + TypeSpec::Alias { + name: "IFarmMemberCreate", + target: "IFarmMemberFields", + }, + TypeSpec::Alias { + name: "IFarmMemberCreateResolve", + target: "IResult<FarmMember>", + }, + TypeSpec::Alias { + name: "IFarmMemberDelete", + target: "IFarmMemberFindOne", + }, + TypeSpec::Alias { + name: "IFarmMemberDeleteResolve", + target: "IResult<string>", + }, + TypeSpec::Object { + name: "IFarmMemberFields", + fields: &[ + FieldSpec::required("farm_id", "string"), + FieldSpec::required("member_pubkey", "string"), + FieldSpec::required("role", "string"), + ], + }, + TypeSpec::Object { + name: "IFarmMemberFieldsFilter", + fields: &[ + FieldSpec::optional("id", "string"), + FieldSpec::optional("created_at", "string"), + FieldSpec::optional("updated_at", "string"), + FieldSpec::optional("farm_id", "string"), + FieldSpec::optional("member_pubkey", "string"), + FieldSpec::optional("role", "string"), + ], + }, + TypeSpec::Object { + name: "IFarmMemberFieldsPartial", + fields: &[ + FieldSpec::optional_nullable("farm_id", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("member_pubkey", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("role", "ReplicaDbJsonValue"), + ], + }, + TypeSpec::Alias { + name: "IFarmMemberFindMany", + target: "IFarmMemberFindManyArgs", + }, + TypeSpec::Object { + name: "IFarmMemberFindManyArgs", + fields: &[FieldSpec::nullable("filter", "IFarmMemberFieldsFilter")], + }, + TypeSpec::Alias { + name: "IFarmMemberFindManyResolve", + target: "IResultList<FarmMember>", + }, + TypeSpec::Union { + name: "IFarmMemberFindOne", + variants: &[VariantSpec::Ref("IFarmMemberFindOneArgs")], + }, + TypeSpec::Object { + name: "IFarmMemberFindOneArgs", + fields: &[FieldSpec::required("on", "FarmMemberQueryBindValues")], + }, + TypeSpec::Alias { + name: "IFarmMemberFindOneResolve", + target: "IResult<FarmMember | null>", + }, + TypeSpec::Alias { + name: "IFarmMemberUpdate", + target: "IFarmMemberUpdateArgs", + }, + TypeSpec::Object { + name: "IFarmMemberUpdateArgs", + fields: &[ + FieldSpec::required("on", "FarmMemberQueryBindValues"), + FieldSpec::required("fields", "IFarmMemberFieldsPartial"), + ], + }, + TypeSpec::Alias { + name: "IFarmMemberUpdateResolve", + target: "IResult<FarmMember>", + }, + TypeSpec::Alias { + name: "IFarmTagCreate", + target: "IFarmTagFields", + }, + TypeSpec::Alias { + name: "IFarmTagCreateResolve", + target: "IResult<FarmTag>", + }, + TypeSpec::Alias { + name: "IFarmTagDelete", + target: "IFarmTagFindOne", + }, + TypeSpec::Alias { + name: "IFarmTagDeleteResolve", + target: "IResult<string>", + }, + TypeSpec::Object { + name: "IFarmTagFields", + fields: &[ + FieldSpec::required("farm_id", "string"), + FieldSpec::required("tag", "string"), + ], + }, + TypeSpec::Object { + name: "IFarmTagFieldsFilter", + fields: &[ + FieldSpec::optional("id", "string"), + FieldSpec::optional("created_at", "string"), + FieldSpec::optional("updated_at", "string"), + FieldSpec::optional("farm_id", "string"), + FieldSpec::optional("tag", "string"), + ], + }, + TypeSpec::Object { + name: "IFarmTagFieldsPartial", + fields: &[ + FieldSpec::optional_nullable("farm_id", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("tag", "ReplicaDbJsonValue"), + ], + }, + TypeSpec::Alias { + name: "IFarmTagFindMany", + target: "IFarmTagFindManyArgs", + }, + TypeSpec::Object { + name: "IFarmTagFindManyArgs", + fields: &[FieldSpec::nullable("filter", "IFarmTagFieldsFilter")], + }, + TypeSpec::Alias { + name: "IFarmTagFindManyResolve", + target: "IResultList<FarmTag>", + }, + TypeSpec::Union { + name: "IFarmTagFindOne", + variants: &[VariantSpec::Ref("IFarmTagFindOneArgs")], + }, + TypeSpec::Object { + name: "IFarmTagFindOneArgs", + fields: &[FieldSpec::required("on", "FarmTagQueryBindValues")], + }, + TypeSpec::Alias { + name: "IFarmTagFindOneResolve", + target: "IResult<FarmTag | null>", + }, + TypeSpec::Alias { + name: "IFarmTagUpdate", + target: "IFarmTagUpdateArgs", + }, + TypeSpec::Object { + name: "IFarmTagUpdateArgs", + fields: &[ + FieldSpec::required("on", "FarmTagQueryBindValues"), + FieldSpec::required("fields", "IFarmTagFieldsPartial"), + ], + }, + TypeSpec::Alias { + name: "IFarmTagUpdateResolve", + target: "IResult<FarmTag>", + }, + TypeSpec::Alias { + name: "IFarmUpdate", + target: "IFarmUpdateArgs", + }, + TypeSpec::Object { + name: "IFarmUpdateArgs", + fields: &[ + FieldSpec::required("on", "FarmQueryBindValues"), + FieldSpec::required("fields", "IFarmFieldsPartial"), + ], + }, + TypeSpec::Alias { + name: "IFarmUpdateResolve", + target: "IResult<Farm>", + }, + TypeSpec::Alias { + name: "IGcsLocationCreate", + target: "IGcsLocationFields", + }, + TypeSpec::Alias { + name: "IGcsLocationCreateResolve", + target: "IResult<GcsLocation>", + }, + TypeSpec::Alias { + name: "IGcsLocationDelete", + target: "IGcsLocationFindOne", + }, + TypeSpec::Alias { + name: "IGcsLocationDeleteResolve", + target: "IResult<string>", + }, + TypeSpec::Object { + name: "IGcsLocationFields", + fields: &[ + FieldSpec::required("d_tag", "string"), + FieldSpec::required("lat", "number"), + FieldSpec::required("lng", "number"), + FieldSpec::required("geohash", "string"), + FieldSpec::required("point", "string"), + FieldSpec::required("polygon", "string"), + FieldSpec::optional_nullable("accuracy", "number"), + FieldSpec::optional_nullable("altitude", "number"), + FieldSpec::optional_nullable("tag_0", "string"), + FieldSpec::optional_nullable("label", "string"), + FieldSpec::optional_nullable("area", "number"), + FieldSpec::optional_nullable("elevation", "number"), + FieldSpec::optional_nullable("soil", "string"), + FieldSpec::optional_nullable("climate", "string"), + FieldSpec::optional_nullable("gc_id", "string"), + FieldSpec::optional_nullable("gc_name", "string"), + FieldSpec::optional_nullable("gc_admin1_id", "string"), + FieldSpec::optional_nullable("gc_admin1_name", "string"), + FieldSpec::optional_nullable("gc_country_id", "string"), + FieldSpec::optional_nullable("gc_country_name", "string"), + ], + }, + TypeSpec::Object { + name: "IGcsLocationFieldsFilter", + fields: &[ + FieldSpec::optional("id", "string"), + FieldSpec::optional("created_at", "string"), + FieldSpec::optional("updated_at", "string"), + FieldSpec::optional("d_tag", "string"), + FieldSpec::optional("lat", "number"), + FieldSpec::optional("lng", "number"), + FieldSpec::optional("geohash", "string"), + FieldSpec::optional("point", "string"), + FieldSpec::optional("polygon", "string"), + FieldSpec::optional("accuracy", "number"), + FieldSpec::optional("altitude", "number"), + FieldSpec::optional("tag_0", "string"), + FieldSpec::optional("label", "string"), + FieldSpec::optional("area", "number"), + FieldSpec::optional("elevation", "number"), + FieldSpec::optional("soil", "string"), + FieldSpec::optional("climate", "string"), + FieldSpec::optional("gc_id", "string"), + FieldSpec::optional("gc_name", "string"), + FieldSpec::optional("gc_admin1_id", "string"), + FieldSpec::optional("gc_admin1_name", "string"), + FieldSpec::optional("gc_country_id", "string"), + FieldSpec::optional("gc_country_name", "string"), + ], + }, + TypeSpec::Object { + name: "IGcsLocationFieldsPartial", + fields: &[ + FieldSpec::optional_nullable("d_tag", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("lat", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("lng", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("geohash", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("point", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("polygon", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("accuracy", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("altitude", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("tag_0", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("label", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("area", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("elevation", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("soil", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("climate", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("gc_id", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("gc_name", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("gc_admin1_id", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("gc_admin1_name", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("gc_country_id", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("gc_country_name", "ReplicaDbJsonValue"), + ], + }, + TypeSpec::Union { + name: "IGcsLocationFindMany", + variants: &[ + VariantSpec::Object(&[FieldSpec::nullable("filter", "IGcsLocationFieldsFilter")]), + VariantSpec::Object(&[FieldSpec::required("rel", "GcsLocationFindManyRel")]), + ], + }, + TypeSpec::Alias { + name: "IGcsLocationFindManyResolve", + target: "IResultList<GcsLocation>", + }, + TypeSpec::Union { + name: "IGcsLocationFindOne", + variants: &[ + VariantSpec::Ref("IGcsLocationFindOneArgs"), + VariantSpec::Ref("IGcsLocationFindOneRelArgs"), + ], + }, + TypeSpec::Object { + name: "IGcsLocationFindOneArgs", + fields: &[FieldSpec::required("on", "GcsLocationQueryBindValues")], + }, + TypeSpec::Object { + name: "IGcsLocationFindOneRelArgs", + fields: &[FieldSpec::required("rel", "GcsLocationFindManyRel")], + }, + TypeSpec::Alias { + name: "IGcsLocationFindOneResolve", + target: "IResult<GcsLocation | null>", + }, + TypeSpec::Alias { + name: "IGcsLocationUpdate", + target: "IGcsLocationUpdateArgs", + }, + TypeSpec::Object { + name: "IGcsLocationUpdateArgs", + fields: &[ + FieldSpec::required("on", "GcsLocationQueryBindValues"), + FieldSpec::required("fields", "IGcsLocationFieldsPartial"), + ], + }, + TypeSpec::Alias { + name: "IGcsLocationUpdateResolve", + target: "IResult<GcsLocation>", + }, + TypeSpec::Alias { + name: "ILogErrorCreate", + target: "ILogErrorFields", + }, + TypeSpec::Alias { + name: "ILogErrorCreateResolve", + target: "IResult<LogError>", + }, + TypeSpec::Alias { + name: "ILogErrorDelete", + target: "ILogErrorFindOne", + }, + TypeSpec::Alias { + name: "ILogErrorDeleteResolve", + target: "IResult<string>", + }, + TypeSpec::Object { + name: "ILogErrorFields", + fields: &[ + FieldSpec::required("error", "string"), + FieldSpec::required("message", "string"), + FieldSpec::optional_nullable("stack_trace", "string"), + FieldSpec::optional_nullable("cause", "string"), + FieldSpec::required("app_system", "string"), + FieldSpec::required("app_version", "string"), + FieldSpec::required("nostr_pubkey", "string"), + FieldSpec::optional_nullable("data", "string"), + ], + }, + TypeSpec::Object { + name: "ILogErrorFieldsFilter", + fields: &[ + FieldSpec::optional("id", "string"), + FieldSpec::optional("created_at", "string"), + FieldSpec::optional("updated_at", "string"), + FieldSpec::optional("error", "string"), + FieldSpec::optional("message", "string"), + FieldSpec::optional("stack_trace", "string"), + FieldSpec::optional("cause", "string"), + FieldSpec::optional("app_system", "string"), + FieldSpec::optional("app_version", "string"), + FieldSpec::optional("nostr_pubkey", "string"), + FieldSpec::optional("data", "string"), + ], + }, + TypeSpec::Object { + name: "ILogErrorFieldsPartial", + fields: &[ + FieldSpec::optional_nullable("error", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("message", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("stack_trace", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("cause", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("app_system", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("app_version", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("nostr_pubkey", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("data", "ReplicaDbJsonValue"), + ], + }, + TypeSpec::Alias { + name: "ILogErrorFindMany", + target: "ILogErrorFindManyArgs", + }, + TypeSpec::Object { + name: "ILogErrorFindManyArgs", + fields: &[FieldSpec::nullable("filter", "ILogErrorFieldsFilter")], + }, + TypeSpec::Alias { + name: "ILogErrorFindManyResolve", + target: "IResultList<LogError>", + }, + TypeSpec::Union { + name: "ILogErrorFindOne", + variants: &[VariantSpec::Ref("ILogErrorFindOneArgs")], + }, + TypeSpec::Object { + name: "ILogErrorFindOneArgs", + fields: &[FieldSpec::required("on", "LogErrorQueryBindValues")], + }, + TypeSpec::Alias { + name: "ILogErrorFindOneResolve", + target: "IResult<LogError | null>", + }, + TypeSpec::Alias { + name: "ILogErrorUpdate", + target: "ILogErrorUpdateArgs", + }, + TypeSpec::Object { + name: "ILogErrorUpdateArgs", + fields: &[ + FieldSpec::required("on", "LogErrorQueryBindValues"), + FieldSpec::required("fields", "ILogErrorFieldsPartial"), + ], + }, + TypeSpec::Alias { + name: "ILogErrorUpdateResolve", + target: "IResult<LogError>", + }, + TypeSpec::Alias { + name: "IMediaImageCreate", + target: "IMediaImageFields", + }, + TypeSpec::Alias { + name: "IMediaImageCreateResolve", + target: "IResult<MediaImage>", + }, + TypeSpec::Alias { + name: "IMediaImageDelete", + target: "IMediaImageFindOne", + }, + TypeSpec::Alias { + name: "IMediaImageDeleteResolve", + target: "IResult<string>", + }, + TypeSpec::Object { + name: "IMediaImageFields", + fields: &[ + FieldSpec::required("file_path", "string"), + FieldSpec::required("mime_type", "string"), + FieldSpec::required("res_base", "string"), + FieldSpec::required("res_path", "string"), + FieldSpec::optional_nullable("label", "string"), + FieldSpec::optional_nullable("description", "string"), + ], + }, + TypeSpec::Object { + name: "IMediaImageFieldsFilter", + fields: &[ + FieldSpec::optional("id", "string"), + FieldSpec::optional("created_at", "string"), + FieldSpec::optional("updated_at", "string"), + FieldSpec::optional("file_path", "string"), + FieldSpec::optional("mime_type", "string"), + FieldSpec::optional("res_base", "string"), + FieldSpec::optional("res_path", "string"), + FieldSpec::optional("label", "string"), + FieldSpec::optional("description", "string"), + ], + }, + TypeSpec::Object { + name: "IMediaImageFieldsPartial", + fields: &[ + FieldSpec::optional_nullable("file_path", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("mime_type", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("res_base", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("res_path", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("label", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("description", "ReplicaDbJsonValue"), + ], + }, + TypeSpec::Union { + name: "IMediaImageFindMany", + variants: &[ + VariantSpec::Object(&[FieldSpec::nullable("filter", "IMediaImageFieldsFilter")]), + VariantSpec::Object(&[FieldSpec::required("rel", "MediaImageFindManyRel")]), + ], + }, + TypeSpec::Alias { + name: "IMediaImageFindManyResolve", + target: "IResultList<MediaImage>", + }, + TypeSpec::Union { + name: "IMediaImageFindOne", + variants: &[ + VariantSpec::Ref("IMediaImageFindOneArgs"), + VariantSpec::Ref("IMediaImageFindOneRelArgs"), + ], + }, + TypeSpec::Object { + name: "IMediaImageFindOneArgs", + fields: &[FieldSpec::required("on", "MediaImageQueryBindValues")], + }, + TypeSpec::Object { + name: "IMediaImageFindOneRelArgs", + fields: &[FieldSpec::required("rel", "MediaImageFindManyRel")], + }, + TypeSpec::Alias { + name: "IMediaImageFindOneResolve", + target: "IResult<MediaImage | null>", + }, + TypeSpec::Alias { + name: "IMediaImageUpdate", + target: "IMediaImageUpdateArgs", + }, + TypeSpec::Object { + name: "IMediaImageUpdateArgs", + fields: &[ + FieldSpec::required("on", "MediaImageQueryBindValues"), + FieldSpec::required("fields", "IMediaImageFieldsPartial"), + ], + }, + TypeSpec::Alias { + name: "IMediaImageUpdateResolve", + target: "IResult<MediaImage>", + }, + TypeSpec::Alias { + name: "INostrEventHeadCreate", + target: "INostrEventHeadFields", + }, + TypeSpec::Alias { + name: "INostrEventHeadCreateResolve", + target: "IResult<NostrEventHead>", + }, + TypeSpec::Alias { + name: "INostrEventHeadDelete", + target: "INostrEventHeadFindOne", + }, + TypeSpec::Alias { + name: "INostrEventHeadDeleteResolve", + target: "IResult<string>", + }, + TypeSpec::Object { + name: "INostrEventHeadFields", + fields: &[ + FieldSpec::required("key", "string"), + FieldSpec::required("kind", "number"), + FieldSpec::required("pubkey", "string"), + FieldSpec::required("d_tag", "string"), + FieldSpec::required("last_event_id", "string"), + FieldSpec::required("last_created_at", "number"), + FieldSpec::required("content_hash", "string"), + ], + }, + TypeSpec::Object { + name: "INostrEventHeadFieldsFilter", + fields: &[ + FieldSpec::optional("id", "string"), + FieldSpec::optional("created_at", "string"), + FieldSpec::optional("updated_at", "string"), + FieldSpec::optional("key", "string"), + FieldSpec::optional("kind", "number"), + FieldSpec::optional("pubkey", "string"), + FieldSpec::optional("d_tag", "string"), + FieldSpec::optional("last_event_id", "string"), + FieldSpec::optional("last_created_at", "number"), + FieldSpec::optional("content_hash", "string"), + ], + }, + TypeSpec::Object { + name: "INostrEventHeadFieldsPartial", + fields: &[ + FieldSpec::optional_nullable("key", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("kind", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("pubkey", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("d_tag", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("last_event_id", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("last_created_at", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("content_hash", "ReplicaDbJsonValue"), + ], + }, + TypeSpec::Alias { + name: "INostrEventHeadFindMany", + target: "INostrEventHeadFindManyArgs", + }, + TypeSpec::Object { + name: "INostrEventHeadFindManyArgs", + fields: &[FieldSpec::nullable("filter", "INostrEventHeadFieldsFilter")], + }, + TypeSpec::Alias { + name: "INostrEventHeadFindManyResolve", + target: "IResultList<NostrEventHead>", + }, + TypeSpec::Union { + name: "INostrEventHeadFindOne", + variants: &[VariantSpec::Ref("INostrEventHeadFindOneArgs")], + }, + TypeSpec::Object { + name: "INostrEventHeadFindOneArgs", + fields: &[FieldSpec::required("on", "NostrEventHeadQueryBindValues")], + }, + TypeSpec::Alias { + name: "INostrEventHeadFindOneResolve", + target: "IResult<NostrEventHead | null>", + }, + TypeSpec::Alias { + name: "INostrEventHeadUpdate", + target: "INostrEventHeadUpdateArgs", + }, + TypeSpec::Object { + name: "INostrEventHeadUpdateArgs", + fields: &[ + FieldSpec::required("on", "NostrEventHeadQueryBindValues"), + FieldSpec::required("fields", "INostrEventHeadFieldsPartial"), + ], + }, + TypeSpec::Alias { + name: "INostrEventHeadUpdateResolve", + target: "IResult<NostrEventHead>", + }, + TypeSpec::Alias { + name: "INostrProfileCreate", + target: "INostrProfileFields", + }, + TypeSpec::Alias { + name: "INostrProfileCreateResolve", + target: "IResult<NostrProfile>", + }, + TypeSpec::Alias { + name: "INostrProfileDelete", + target: "INostrProfileFindOne", + }, + TypeSpec::Alias { + name: "INostrProfileDeleteResolve", + target: "IResult<string>", + }, + TypeSpec::Object { + name: "INostrProfileFields", + fields: &[ + FieldSpec::required("public_key", "string"), + FieldSpec::required("profile_type", "string"), + FieldSpec::required("name", "string"), + FieldSpec::optional_nullable("display_name", "string"), + FieldSpec::optional_nullable("about", "string"), + FieldSpec::optional_nullable("website", "string"), + FieldSpec::optional_nullable("picture", "string"), + FieldSpec::optional_nullable("banner", "string"), + FieldSpec::optional_nullable("nip05", "string"), + FieldSpec::optional_nullable("lud06", "string"), + FieldSpec::optional_nullable("lud16", "string"), + ], + }, + TypeSpec::Object { + name: "INostrProfileFieldsFilter", + fields: &[ + FieldSpec::optional("id", "string"), + FieldSpec::optional("created_at", "string"), + FieldSpec::optional("updated_at", "string"), + FieldSpec::optional("public_key", "string"), + FieldSpec::optional("profile_type", "string"), + FieldSpec::optional("name", "string"), + FieldSpec::optional("display_name", "string"), + FieldSpec::optional("about", "string"), + FieldSpec::optional("website", "string"), + FieldSpec::optional("picture", "string"), + FieldSpec::optional("banner", "string"), + FieldSpec::optional("nip05", "string"), + FieldSpec::optional("lud06", "string"), + FieldSpec::optional("lud16", "string"), + ], + }, + TypeSpec::Object { + name: "INostrProfileFieldsPartial", + fields: &[ + FieldSpec::optional_nullable("public_key", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("profile_type", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("name", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("display_name", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("about", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("website", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("picture", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("banner", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("nip05", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("lud06", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("lud16", "ReplicaDbJsonValue"), + ], + }, + TypeSpec::Union { + name: "INostrProfileFindMany", + variants: &[ + VariantSpec::Object(&[FieldSpec::nullable("filter", "INostrProfileFieldsFilter")]), + VariantSpec::Object(&[FieldSpec::required("rel", "NostrProfileFindManyRel")]), + ], + }, + TypeSpec::Alias { + name: "INostrProfileFindManyResolve", + target: "IResultList<NostrProfile>", + }, + TypeSpec::Union { + name: "INostrProfileFindOne", + variants: &[ + VariantSpec::Ref("INostrProfileFindOneArgs"), + VariantSpec::Ref("INostrProfileFindOneRelArgs"), + ], + }, + TypeSpec::Object { + name: "INostrProfileFindOneArgs", + fields: &[FieldSpec::required("on", "NostrProfileQueryBindValues")], + }, + TypeSpec::Object { + name: "INostrProfileFindOneRelArgs", + fields: &[FieldSpec::required("rel", "NostrProfileFindManyRel")], + }, + TypeSpec::Alias { + name: "INostrProfileFindOneResolve", + target: "IResult<NostrProfile | null>", + }, + TypeSpec::Object { + name: "INostrProfileRelayRelation", + fields: &[ + FieldSpec::required("nostr_profile", "NostrProfileQueryBindValues"), + FieldSpec::required("nostr_relay", "NostrRelayQueryBindValues"), + ], + }, + TypeSpec::Alias { + name: "INostrProfileRelayResolve", + target: "IResultPass", + }, + TypeSpec::Alias { + name: "INostrProfileUpdate", + target: "INostrProfileUpdateArgs", + }, + TypeSpec::Object { + name: "INostrProfileUpdateArgs", + fields: &[ + FieldSpec::required("on", "NostrProfileQueryBindValues"), + FieldSpec::required("fields", "INostrProfileFieldsPartial"), + ], + }, + TypeSpec::Alias { + name: "INostrProfileUpdateResolve", + target: "IResult<NostrProfile>", + }, + TypeSpec::Alias { + name: "INostrRelayCreate", + target: "INostrRelayFields", + }, + TypeSpec::Alias { + name: "INostrRelayCreateResolve", + target: "IResult<NostrRelay>", + }, + TypeSpec::Alias { + name: "INostrRelayDelete", + target: "INostrRelayFindOne", + }, + TypeSpec::Alias { + name: "INostrRelayDeleteResolve", + target: "IResult<string>", + }, + TypeSpec::Object { + name: "INostrRelayFields", + fields: &[ + FieldSpec::required("url", "string"), + FieldSpec::optional_nullable("relay_id", "string"), + FieldSpec::optional_nullable("name", "string"), + FieldSpec::optional_nullable("description", "string"), + FieldSpec::optional_nullable("pubkey", "string"), + FieldSpec::optional_nullable("contact", "string"), + FieldSpec::optional_nullable("supported_nips", "string"), + FieldSpec::optional_nullable("software", "string"), + FieldSpec::optional_nullable("version", "string"), + FieldSpec::optional_nullable("data", "string"), + ], + }, + TypeSpec::Object { + name: "INostrRelayFieldsFilter", + fields: &[ + FieldSpec::optional("id", "string"), + FieldSpec::optional("created_at", "string"), + FieldSpec::optional("updated_at", "string"), + FieldSpec::optional("url", "string"), + FieldSpec::optional("relay_id", "string"), + FieldSpec::optional("name", "string"), + FieldSpec::optional("description", "string"), + FieldSpec::optional("pubkey", "string"), + FieldSpec::optional("contact", "string"), + FieldSpec::optional("supported_nips", "string"), + FieldSpec::optional("software", "string"), + FieldSpec::optional("version", "string"), + FieldSpec::optional("data", "string"), + ], + }, + TypeSpec::Object { + name: "INostrRelayFieldsPartial", + fields: &[ + FieldSpec::optional_nullable("url", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("relay_id", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("name", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("description", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("pubkey", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("contact", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("supported_nips", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("software", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("version", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("data", "ReplicaDbJsonValue"), + ], + }, + TypeSpec::Union { + name: "INostrRelayFindMany", + variants: &[ + VariantSpec::Object(&[FieldSpec::nullable("filter", "INostrRelayFieldsFilter")]), + VariantSpec::Object(&[FieldSpec::required("rel", "NostrRelayFindManyRel")]), + ], + }, + TypeSpec::Alias { + name: "INostrRelayFindManyResolve", + target: "IResultList<NostrRelay>", + }, + TypeSpec::Union { + name: "INostrRelayFindOne", + variants: &[ + VariantSpec::Ref("INostrRelayFindOneArgs"), + VariantSpec::Ref("INostrRelayFindOneRelArgs"), + ], + }, + TypeSpec::Object { + name: "INostrRelayFindOneArgs", + fields: &[FieldSpec::required("on", "NostrRelayQueryBindValues")], + }, + TypeSpec::Object { + name: "INostrRelayFindOneRelArgs", + fields: &[FieldSpec::required("rel", "NostrRelayFindManyRel")], + }, + TypeSpec::Alias { + name: "INostrRelayFindOneResolve", + target: "IResult<NostrRelay | null>", + }, + TypeSpec::Alias { + name: "INostrRelayUpdate", + target: "INostrRelayUpdateArgs", + }, + TypeSpec::Object { + name: "INostrRelayUpdateArgs", + fields: &[ + FieldSpec::required("on", "NostrRelayQueryBindValues"), + FieldSpec::required("fields", "INostrRelayFieldsPartial"), + ], + }, + TypeSpec::Alias { + name: "INostrRelayUpdateResolve", + target: "IResult<NostrRelay>", + }, + TypeSpec::Alias { + name: "IPlotCreate", + target: "IPlotFields", + }, + TypeSpec::Alias { + name: "IPlotCreateResolve", + target: "IResult<Plot>", + }, + TypeSpec::Alias { + name: "IPlotDelete", + target: "IPlotFindOne", + }, + TypeSpec::Alias { + name: "IPlotDeleteResolve", + target: "IResult<string>", + }, + TypeSpec::Object { + name: "IPlotFields", + fields: &[ + FieldSpec::required("d_tag", "string"), + FieldSpec::required("farm_id", "string"), + FieldSpec::required("name", "string"), + FieldSpec::optional_nullable("about", "string"), + FieldSpec::optional_nullable("location_primary", "string"), + FieldSpec::optional_nullable("location_city", "string"), + FieldSpec::optional_nullable("location_region", "string"), + FieldSpec::optional_nullable("location_country", "string"), + ], + }, + TypeSpec::Object { + name: "IPlotFieldsFilter", + fields: &[ + FieldSpec::optional("id", "string"), + FieldSpec::optional("created_at", "string"), + FieldSpec::optional("updated_at", "string"), + FieldSpec::optional("d_tag", "string"), + FieldSpec::optional("farm_id", "string"), + FieldSpec::optional("name", "string"), + FieldSpec::optional("about", "string"), + FieldSpec::optional("location_primary", "string"), + FieldSpec::optional("location_city", "string"), + FieldSpec::optional("location_region", "string"), + FieldSpec::optional("location_country", "string"), + ], + }, + TypeSpec::Object { + name: "IPlotFieldsPartial", + fields: &[ + FieldSpec::optional_nullable("d_tag", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("farm_id", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("name", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("about", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("location_primary", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("location_city", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("location_region", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("location_country", "ReplicaDbJsonValue"), + ], + }, + TypeSpec::Alias { + name: "IPlotFindMany", + target: "IPlotFindManyArgs", + }, + TypeSpec::Object { + name: "IPlotFindManyArgs", + fields: &[FieldSpec::nullable("filter", "IPlotFieldsFilter")], + }, + TypeSpec::Alias { + name: "IPlotFindManyResolve", + target: "IResultList<Plot>", + }, + TypeSpec::Union { + name: "IPlotFindOne", + variants: &[VariantSpec::Ref("IPlotFindOneArgs")], + }, + TypeSpec::Object { + name: "IPlotFindOneArgs", + fields: &[FieldSpec::required("on", "PlotQueryBindValues")], + }, + TypeSpec::Alias { + name: "IPlotFindOneResolve", + target: "IResult<Plot | null>", + }, + TypeSpec::Alias { + name: "IPlotGcsLocationCreate", + target: "IPlotGcsLocationFields", + }, + TypeSpec::Alias { + name: "IPlotGcsLocationCreateResolve", + target: "IResult<PlotGcsLocation>", + }, + TypeSpec::Alias { + name: "IPlotGcsLocationDelete", + target: "IPlotGcsLocationFindOne", + }, + TypeSpec::Alias { + name: "IPlotGcsLocationDeleteResolve", + target: "IResult<string>", + }, + TypeSpec::Object { + name: "IPlotGcsLocationFields", + fields: &[ + FieldSpec::required("plot_id", "string"), + FieldSpec::required("gcs_location_id", "string"), + FieldSpec::required("role", "string"), + ], + }, + TypeSpec::Object { + name: "IPlotGcsLocationFieldsFilter", + fields: &[ + FieldSpec::optional("id", "string"), + FieldSpec::optional("created_at", "string"), + FieldSpec::optional("updated_at", "string"), + FieldSpec::optional("plot_id", "string"), + FieldSpec::optional("gcs_location_id", "string"), + FieldSpec::optional("role", "string"), + ], + }, + TypeSpec::Object { + name: "IPlotGcsLocationFieldsPartial", + fields: &[ + FieldSpec::optional_nullable("plot_id", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("gcs_location_id", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("role", "ReplicaDbJsonValue"), + ], + }, + TypeSpec::Alias { + name: "IPlotGcsLocationFindMany", + target: "IPlotGcsLocationFindManyArgs", + }, + TypeSpec::Object { + name: "IPlotGcsLocationFindManyArgs", + fields: &[FieldSpec::nullable( + "filter", + "IPlotGcsLocationFieldsFilter", + )], + }, + TypeSpec::Alias { + name: "IPlotGcsLocationFindManyResolve", + target: "IResultList<PlotGcsLocation>", + }, + TypeSpec::Union { + name: "IPlotGcsLocationFindOne", + variants: &[VariantSpec::Ref("IPlotGcsLocationFindOneArgs")], + }, + TypeSpec::Object { + name: "IPlotGcsLocationFindOneArgs", + fields: &[FieldSpec::required("on", "PlotGcsLocationQueryBindValues")], + }, + TypeSpec::Alias { + name: "IPlotGcsLocationFindOneResolve", + target: "IResult<PlotGcsLocation | null>", + }, + TypeSpec::Alias { + name: "IPlotGcsLocationUpdate", + target: "IPlotGcsLocationUpdateArgs", + }, + TypeSpec::Object { + name: "IPlotGcsLocationUpdateArgs", + fields: &[ + FieldSpec::required("on", "PlotGcsLocationQueryBindValues"), + FieldSpec::required("fields", "IPlotGcsLocationFieldsPartial"), + ], + }, + TypeSpec::Alias { + name: "IPlotGcsLocationUpdateResolve", + target: "IResult<PlotGcsLocation>", + }, + TypeSpec::Alias { + name: "IPlotTagCreate", + target: "IPlotTagFields", + }, + TypeSpec::Alias { + name: "IPlotTagCreateResolve", + target: "IResult<PlotTag>", + }, + TypeSpec::Alias { + name: "IPlotTagDelete", + target: "IPlotTagFindOne", + }, + TypeSpec::Alias { + name: "IPlotTagDeleteResolve", + target: "IResult<string>", + }, + TypeSpec::Object { + name: "IPlotTagFields", + fields: &[ + FieldSpec::required("plot_id", "string"), + FieldSpec::required("tag", "string"), + ], + }, + TypeSpec::Object { + name: "IPlotTagFieldsFilter", + fields: &[ + FieldSpec::optional("id", "string"), + FieldSpec::optional("created_at", "string"), + FieldSpec::optional("updated_at", "string"), + FieldSpec::optional("plot_id", "string"), + FieldSpec::optional("tag", "string"), + ], + }, + TypeSpec::Object { + name: "IPlotTagFieldsPartial", + fields: &[ + FieldSpec::optional_nullable("plot_id", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("tag", "ReplicaDbJsonValue"), + ], + }, + TypeSpec::Alias { + name: "IPlotTagFindMany", + target: "IPlotTagFindManyArgs", + }, + TypeSpec::Object { + name: "IPlotTagFindManyArgs", + fields: &[FieldSpec::nullable("filter", "IPlotTagFieldsFilter")], + }, + TypeSpec::Alias { + name: "IPlotTagFindManyResolve", + target: "IResultList<PlotTag>", + }, + TypeSpec::Union { + name: "IPlotTagFindOne", + variants: &[VariantSpec::Ref("IPlotTagFindOneArgs")], + }, + TypeSpec::Object { + name: "IPlotTagFindOneArgs", + fields: &[FieldSpec::required("on", "PlotTagQueryBindValues")], + }, + TypeSpec::Alias { + name: "IPlotTagFindOneResolve", + target: "IResult<PlotTag | null>", + }, + TypeSpec::Alias { + name: "IPlotTagUpdate", + target: "IPlotTagUpdateArgs", + }, + TypeSpec::Object { + name: "IPlotTagUpdateArgs", + fields: &[ + FieldSpec::required("on", "PlotTagQueryBindValues"), + FieldSpec::required("fields", "IPlotTagFieldsPartial"), + ], + }, + TypeSpec::Alias { + name: "IPlotTagUpdateResolve", + target: "IResult<PlotTag>", + }, + TypeSpec::Alias { + name: "IPlotUpdate", + target: "IPlotUpdateArgs", + }, + TypeSpec::Object { + name: "IPlotUpdateArgs", + fields: &[ + FieldSpec::required("on", "PlotQueryBindValues"), + FieldSpec::required("fields", "IPlotFieldsPartial"), + ], + }, + TypeSpec::Alias { + name: "IPlotUpdateResolve", + target: "IResult<Plot>", + }, + TypeSpec::Alias { + name: "ITradeProductCreate", + target: "ITradeProductFields", + }, + TypeSpec::Alias { + name: "ITradeProductCreateResolve", + target: "IResult<TradeProduct>", + }, + TypeSpec::Alias { + name: "ITradeProductDelete", + target: "ITradeProductFindOne", + }, + TypeSpec::Alias { + name: "ITradeProductDeleteResolve", + target: "IResult<string>", + }, + TypeSpec::Object { + name: "ITradeProductFields", + fields: &[ + FieldSpec::required("key", "string"), + FieldSpec::required("category", "string"), + FieldSpec::required("title", "string"), + FieldSpec::required("summary", "string"), + FieldSpec::required("process", "string"), + FieldSpec::required("lot", "string"), + FieldSpec::required("profile", "string"), + FieldSpec::required("year", "bigint"), + FieldSpec::required("qty_amt", "number"), + FieldSpec::required("qty_amt_exact", "string"), + FieldSpec::required("qty_unit", "string"), + FieldSpec::optional_nullable("qty_label", "string"), + FieldSpec::optional_nullable("qty_avail", "bigint"), + FieldSpec::required("price_amt", "number"), + FieldSpec::required("price_amt_exact", "string"), + FieldSpec::required("price_currency", "string"), + FieldSpec::required("price_qty_amt", "number"), + FieldSpec::required("price_qty_amt_exact", "string"), + FieldSpec::required("price_qty_unit", "string"), + FieldSpec::optional_nullable("listing_addr", "string"), + FieldSpec::optional_nullable("primary_bin_id", "string"), + FieldSpec::optional_nullable("verified_primary_bin_id", "string"), + FieldSpec::optional_nullable("notes", "string"), + ], + }, + TypeSpec::Object { + name: "ITradeProductFieldsFilter", + fields: &[ + FieldSpec::optional("id", "string"), + FieldSpec::optional("created_at", "string"), + FieldSpec::optional("updated_at", "string"), + FieldSpec::optional("key", "string"), + FieldSpec::optional("category", "string"), + FieldSpec::optional("title", "string"), + FieldSpec::optional("summary", "string"), + FieldSpec::optional("process", "string"), + FieldSpec::optional("lot", "string"), + FieldSpec::optional("profile", "string"), + FieldSpec::optional("year", "bigint"), + FieldSpec::optional("qty_amt", "number"), + FieldSpec::optional("qty_amt_exact", "string"), + FieldSpec::optional("qty_unit", "string"), + FieldSpec::optional("qty_label", "string"), + FieldSpec::optional("qty_avail", "bigint"), + FieldSpec::optional("price_amt", "number"), + FieldSpec::optional("price_amt_exact", "string"), + FieldSpec::optional("price_currency", "string"), + FieldSpec::optional("price_qty_amt", "number"), + FieldSpec::optional("price_qty_amt_exact", "string"), + FieldSpec::optional("price_qty_unit", "string"), + FieldSpec::optional("listing_addr", "string"), + FieldSpec::optional("primary_bin_id", "string"), + FieldSpec::optional("verified_primary_bin_id", "string"), + FieldSpec::optional("notes", "string"), + ], + }, + TypeSpec::Object { + name: "ITradeProductFieldsPartial", + fields: &[ + FieldSpec::optional_nullable("key", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("category", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("title", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("summary", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("process", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("lot", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("profile", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("year", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("qty_amt", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("qty_amt_exact", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("qty_unit", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("qty_label", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("qty_avail", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("price_amt", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("price_amt_exact", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("price_currency", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("price_qty_amt", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("price_qty_amt_exact", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("price_qty_unit", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("listing_addr", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("primary_bin_id", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("verified_primary_bin_id", "ReplicaDbJsonValue"), + FieldSpec::optional_nullable("notes", "ReplicaDbJsonValue"), + ], + }, + TypeSpec::Alias { + name: "ITradeProductFindMany", + target: "ITradeProductFindManyArgs", + }, + TypeSpec::Object { + name: "ITradeProductFindManyArgs", + fields: &[FieldSpec::nullable("filter", "ITradeProductFieldsFilter")], + }, + TypeSpec::Alias { + name: "ITradeProductFindManyResolve", + target: "IResultList<TradeProduct>", + }, + TypeSpec::Union { + name: "ITradeProductFindOne", + variants: &[VariantSpec::Ref("ITradeProductFindOneArgs")], + }, + TypeSpec::Object { + name: "ITradeProductFindOneArgs", + fields: &[FieldSpec::required("on", "TradeProductQueryBindValues")], + }, + TypeSpec::Alias { + name: "ITradeProductFindOneResolve", + target: "IResult<TradeProduct | null>", + }, + TypeSpec::Object { + name: "ITradeProductLocationRelation", + fields: &[ + FieldSpec::required("trade_product", "TradeProductQueryBindValues"), + FieldSpec::required("gcs_location", "GcsLocationQueryBindValues"), + ], + }, + TypeSpec::Alias { + name: "ITradeProductLocationResolve", + target: "IResultPass", + }, + TypeSpec::Object { + name: "ITradeProductMediaRelation", + fields: &[ + FieldSpec::required("trade_product", "TradeProductQueryBindValues"), + FieldSpec::required("media_image", "MediaImageQueryBindValues"), + ], + }, + TypeSpec::Alias { + name: "ITradeProductMediaResolve", + target: "IResultPass", + }, + TypeSpec::Alias { + name: "ITradeProductUpdate", + target: "ITradeProductUpdateArgs", + }, + TypeSpec::Object { + name: "ITradeProductUpdateArgs", + fields: &[ + FieldSpec::required("on", "TradeProductQueryBindValues"), + FieldSpec::required("fields", "ITradeProductFieldsPartial"), + ], + }, + TypeSpec::Alias { + name: "ITradeProductUpdateResolve", + target: "IResult<TradeProduct>", + }, + TypeSpec::Object { + name: "LogError", + fields: &[ + FieldSpec::required("id", "string"), + FieldSpec::required("created_at", "string"), + FieldSpec::required("updated_at", "string"), + FieldSpec::required("error", "string"), + FieldSpec::required("message", "string"), + FieldSpec::nullable("stack_trace", "string"), + FieldSpec::nullable("cause", "string"), + FieldSpec::required("app_system", "string"), + FieldSpec::required("app_version", "string"), + FieldSpec::required("nostr_pubkey", "string"), + FieldSpec::nullable("data", "string"), + ], + }, + TypeSpec::Union { + name: "LogErrorQueryBindValues", + variants: &[ + VariantSpec::Object(&[FieldSpec::required("id", "string")]), + VariantSpec::Object(&[FieldSpec::required("nostr_pubkey", "string")]), + ], + }, + TypeSpec::Object { + name: "MediaImage", + fields: &[ + FieldSpec::required("id", "string"), + FieldSpec::required("created_at", "string"), + FieldSpec::required("updated_at", "string"), + FieldSpec::required("file_path", "string"), + FieldSpec::required("mime_type", "string"), + FieldSpec::required("res_base", "string"), + FieldSpec::required("res_path", "string"), + FieldSpec::nullable("label", "string"), + FieldSpec::nullable("description", "string"), + ], + }, + TypeSpec::Union { + name: "MediaImageFindManyRel", + variants: &[ + VariantSpec::Object(&[FieldSpec::required( + "on_trade_product", + "MediaImageTradeProductArgs", + )]), + VariantSpec::Object(&[FieldSpec::required( + "off_trade_product", + "MediaImageTradeProductArgs", + )]), + ], + }, + TypeSpec::Union { + name: "MediaImageQueryBindValues", + variants: &[ + VariantSpec::Object(&[FieldSpec::required("id", "string")]), + VariantSpec::Object(&[FieldSpec::required("file_path", "string")]), + ], + }, + TypeSpec::Object { + name: "MediaImageTradeProductArgs", + fields: &[FieldSpec::required("id", "string")], + }, + TypeSpec::Object { + name: "NostrEventHead", + fields: &[ + FieldSpec::required("id", "string"), + FieldSpec::required("created_at", "string"), + FieldSpec::required("updated_at", "string"), + FieldSpec::required("key", "string"), + FieldSpec::required("kind", "number"), + FieldSpec::required("pubkey", "string"), + FieldSpec::required("d_tag", "string"), + FieldSpec::required("last_event_id", "string"), + FieldSpec::required("last_created_at", "number"), + FieldSpec::required("content_hash", "string"), + ], + }, + TypeSpec::Union { + name: "NostrEventHeadQueryBindValues", + variants: &[ + VariantSpec::Object(&[FieldSpec::required("id", "string")]), + VariantSpec::Object(&[FieldSpec::required("key", "string")]), + ], + }, + TypeSpec::Object { + name: "NostrProfile", + fields: &[ + FieldSpec::required("id", "string"), + FieldSpec::required("created_at", "string"), + FieldSpec::required("updated_at", "string"), + FieldSpec::required("public_key", "string"), + FieldSpec::required("profile_type", "string"), + FieldSpec::required("name", "string"), + FieldSpec::nullable("display_name", "string"), + FieldSpec::nullable("about", "string"), + FieldSpec::nullable("website", "string"), + FieldSpec::nullable("picture", "string"), + FieldSpec::nullable("banner", "string"), + FieldSpec::nullable("nip05", "string"), + FieldSpec::nullable("lud06", "string"), + FieldSpec::nullable("lud16", "string"), + ], + }, + TypeSpec::Union { + name: "NostrProfileFindManyRel", + variants: &[ + VariantSpec::Object(&[FieldSpec::required("on_relay", "NostrProfileRelayArgs")]), + VariantSpec::Object(&[FieldSpec::required("off_relay", "NostrProfileRelayArgs")]), + ], + }, + TypeSpec::Union { + name: "NostrProfileQueryBindValues", + variants: &[ + VariantSpec::Object(&[FieldSpec::required("id", "string")]), + VariantSpec::Object(&[FieldSpec::required("public_key", "string")]), + ], + }, + TypeSpec::Object { + name: "NostrProfileRelayArgs", + fields: &[FieldSpec::required("id", "string")], + }, + TypeSpec::Object { + name: "NostrRelay", + fields: &[ + FieldSpec::required("id", "string"), + FieldSpec::required("created_at", "string"), + FieldSpec::required("updated_at", "string"), + FieldSpec::required("url", "string"), + FieldSpec::nullable("relay_id", "string"), + FieldSpec::nullable("name", "string"), + FieldSpec::nullable("description", "string"), + FieldSpec::nullable("pubkey", "string"), + FieldSpec::nullable("contact", "string"), + FieldSpec::nullable("supported_nips", "string"), + FieldSpec::nullable("software", "string"), + FieldSpec::nullable("version", "string"), + FieldSpec::nullable("data", "string"), + ], + }, + TypeSpec::Union { + name: "NostrRelayFindManyRel", + variants: &[ + VariantSpec::Object(&[FieldSpec::required("on_profile", "NostrRelayProfileArgs")]), + VariantSpec::Object(&[FieldSpec::required("off_profile", "NostrRelayProfileArgs")]), + ], + }, + TypeSpec::Object { + name: "NostrRelayProfileArgs", + fields: &[FieldSpec::required("public_key", "string")], + }, + TypeSpec::Union { + name: "NostrRelayQueryBindValues", + variants: &[ + VariantSpec::Object(&[FieldSpec::required("id", "string")]), + VariantSpec::Object(&[FieldSpec::required("url", "string")]), + ], + }, + TypeSpec::Object { + name: "Plot", + fields: &[ + FieldSpec::required("id", "string"), + FieldSpec::required("created_at", "string"), + FieldSpec::required("updated_at", "string"), + FieldSpec::required("d_tag", "string"), + FieldSpec::required("farm_id", "string"), + FieldSpec::required("name", "string"), + FieldSpec::nullable("about", "string"), + FieldSpec::nullable("location_primary", "string"), + FieldSpec::nullable("location_city", "string"), + FieldSpec::nullable("location_region", "string"), + FieldSpec::nullable("location_country", "string"), + ], + }, + TypeSpec::Object { + name: "PlotGcsLocation", + fields: &[ + FieldSpec::required("id", "string"), + FieldSpec::required("created_at", "string"), + FieldSpec::required("updated_at", "string"), + FieldSpec::required("plot_id", "string"), + FieldSpec::required("gcs_location_id", "string"), + FieldSpec::required("role", "string"), + ], + }, + TypeSpec::Union { + name: "PlotGcsLocationQueryBindValues", + variants: &[ + VariantSpec::Object(&[FieldSpec::required("id", "string")]), + VariantSpec::Object(&[FieldSpec::required("plot_id", "string")]), + VariantSpec::Object(&[FieldSpec::required("gcs_location_id", "string")]), + ], + }, + TypeSpec::Union { + name: "PlotQueryBindValues", + variants: &[ + VariantSpec::Object(&[FieldSpec::required("id", "string")]), + VariantSpec::Object(&[FieldSpec::required("d_tag", "string")]), + VariantSpec::Object(&[FieldSpec::required("farm_id", "string")]), + ], + }, + TypeSpec::Object { + name: "PlotTag", + fields: &[ + FieldSpec::required("id", "string"), + FieldSpec::required("created_at", "string"), + FieldSpec::required("updated_at", "string"), + FieldSpec::required("plot_id", "string"), + FieldSpec::required("tag", "string"), + ], + }, + TypeSpec::Union { + name: "PlotTagQueryBindValues", + variants: &[ + VariantSpec::Object(&[FieldSpec::required("id", "string")]), + VariantSpec::Object(&[FieldSpec::required("plot_id", "string")]), + VariantSpec::Object(&[FieldSpec::required("tag", "string")]), + ], + }, + TypeSpec::Alias { + name: "ReplicaDbJsonValue", + target: "null | boolean | number | string | Array<ReplicaDbJsonValue> | { [key: string]: ReplicaDbJsonValue }", + }, + TypeSpec::Object { + name: "TradeProduct", + fields: &[ + FieldSpec::required("id", "string"), + FieldSpec::required("created_at", "string"), + FieldSpec::required("updated_at", "string"), + FieldSpec::required("key", "string"), + FieldSpec::required("category", "string"), + FieldSpec::required("title", "string"), + FieldSpec::required("summary", "string"), + FieldSpec::required("process", "string"), + FieldSpec::required("lot", "string"), + FieldSpec::required("profile", "string"), + FieldSpec::required("year", "bigint"), + FieldSpec::required("qty_amt", "number"), + FieldSpec::nullable("qty_amt_exact", "string"), + FieldSpec::required("qty_unit", "string"), + FieldSpec::nullable("qty_label", "string"), + FieldSpec::nullable("qty_avail", "bigint"), + FieldSpec::required("price_amt", "number"), + FieldSpec::nullable("price_amt_exact", "string"), + FieldSpec::required("price_currency", "string"), + FieldSpec::required("price_qty_amt", "number"), + FieldSpec::nullable("price_qty_amt_exact", "string"), + FieldSpec::required("price_qty_unit", "string"), + FieldSpec::nullable("listing_addr", "string"), + FieldSpec::nullable("primary_bin_id", "string"), + FieldSpec::nullable("verified_primary_bin_id", "string"), + FieldSpec::nullable("notes", "string"), + ], + }, + TypeSpec::Union { + name: "TradeProductQueryBindValues", + variants: &[VariantSpec::Object(&[FieldSpec::required("id", "string")])], + }, +]; + +#[cfg(test)] +mod tests { + use super::{FieldSpec, TYPE_SPECS, TypeSpec, VariantSpec, dto_registry, type_inventory}; + + #[test] + fn registry_exports_known_schema_types() { + let registry = dto_registry(); + assert!(!registry.has_errors(), "{:?}", registry.diagnostics); + assert!(type_inventory().contains(&"Farm")); + assert!(type_inventory().contains(&"NostrEventHead")); + assert!(type_inventory().contains(&"ReplicaDbJsonValue")); + } + + #[test] + fn source_find_one_resolves_preserve_nullable_result() { + assert!(TYPE_SPECS.iter().any(|spec| matches!( + spec, + TypeSpec::Alias { + name: "IFarmFindOneResolve", + target: "IResult<Farm | null>" + } + ))); + } + + #[test] + fn relation_find_many_inputs_preserve_filter_and_rel_variants() { + for (name, filter, rel) in [ + ( + "IGcsLocationFindMany", + "IGcsLocationFieldsFilter", + "GcsLocationFindManyRel", + ), + ( + "IMediaImageFindMany", + "IMediaImageFieldsFilter", + "MediaImageFindManyRel", + ), + ( + "INostrProfileFindMany", + "INostrProfileFieldsFilter", + "NostrProfileFindManyRel", + ), + ( + "INostrRelayFindMany", + "INostrRelayFieldsFilter", + "NostrRelayFindManyRel", + ), + ] { + assert!(TYPE_SPECS.iter().any(|spec| matches!( + spec, + TypeSpec::Union { name: actual_name, variants } + if *actual_name == name + && variants.len() == 2 + && matches!(variants[0], VariantSpec::Object(fields) if fields.len() == 1 && fields[0] == FieldSpec::nullable("filter", filter)) + && matches!(variants[1], VariantSpec::Object(fields) if fields.len() == 1 && fields[0] == FieldSpec::required("rel", rel)) + ))); + } + } + + #[test] + fn serde_json_value_policy_is_explicit() { + assert!(TYPE_SPECS.iter().any(|spec| matches!( + spec, + TypeSpec::Alias { name: "ReplicaDbJsonValue", target } if target.contains("[key: string]: ReplicaDbJsonValue") + ))); + assert!(TYPE_SPECS.iter().any(|spec| matches!( + spec, + TypeSpec::Object { name: "ITradeProductFieldsPartial", fields } if fields.iter().any(|field| field.name == "year" && field.target == "ReplicaDbJsonValue" && field.optional && field.nullable) + ))); + } + + #[test] + fn trade_product_large_integer_policy_is_explicit() { + assert!(TYPE_SPECS.iter().any(|spec| matches!( + spec, + TypeSpec::Object { name: "TradeProduct", fields } if fields.iter().any(|field| field.name == "year" && field.target == "bigint") + ))); + assert!(TYPE_SPECS.iter().any(|spec| matches!( + spec, + TypeSpec::Object { name: "ITradeProductFieldsFilter", fields } if fields.iter().any(|field| field.name == "qty_avail" && field.target == "bigint" && field.optional) + ))); + } +} diff --git a/crates/replica_db_schema/src/lib.rs b/crates/replica_db_schema/src/lib.rs @@ -1,3 +1,6 @@ +#[cfg(feature = "dto-bindgen")] +pub mod dto; + pub mod models; pub use models::*; diff --git a/crates/trade/Cargo.toml b/crates/trade/Cargo.toml @@ -14,6 +14,14 @@ readme = "README" [features] default = ["std", "serde", "serde_json"] +dto-bindgen = [ + "std", + "serde_json", + "dep:dto_bindgen", + "dep:dto_bindgen_core", + "radroots_core/dto-bindgen", + "radroots_events/dto-bindgen", +] std = [ "radroots_authority/std", "radroots_core/std", @@ -49,6 +57,8 @@ radroots_events = { workspace = true, default-features = false } radroots_events_codec = { workspace = true, default-features = false } radroots_event_store = { workspace = true, optional = true, default-features = false } base64 = { workspace = true, optional = true } +dto_bindgen = { workspace = true, optional = true } +dto_bindgen_core = { workspace = true, optional = true } hex = { workspace = true, optional = true } serde = { workspace = true, default-features = false, features = [ "alloc", diff --git a/crates/trade/src/dto.rs b/crates/trade/src/dto.rs @@ -0,0 +1,315 @@ +use dto_bindgen_core::{ + BackendId, DescribeCtx, Dto, FieldDef, IdentName, RootDescriptor, RustTypeId, SourceSpan, + StructDef, TargetFieldNames, TargetOverride, TypeDef, TypeRef, WireFieldNames, +}; + +use crate::listing::{ + model::{RadrootsTradeListingSubtotal, RadrootsTradeListingTotal}, + validation::RadrootsTradeListing, +}; + +pub fn dto_roots() -> [RootDescriptor; 3] { + [ + RootDescriptor::new::<RadrootsTradeListing>(), + RootDescriptor::new::<RadrootsTradeListingSubtotal>(), + RootDescriptor::new::<RadrootsTradeListingTotal>(), + ] +} + +impl Dto for RadrootsTradeListing { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + let def = StructDef::new( + "RadrootsTradeListing", + "RadrootsTradeListing", + span("crates/trade/src/listing/validation.rs", 25), + ) + .with_field(field( + "listing_id", + "listing_id", + String::describe(ctx), + "crates/trade/src/listing/validation.rs", + 26, + )) + .with_field(field( + "listing_addr", + "listing_addr", + String::describe(ctx), + "crates/trade/src/listing/validation.rs", + 27, + )) + .with_field(field( + "seller_pubkey", + "seller_pubkey", + String::describe(ctx), + "crates/trade/src/listing/validation.rs", + 28, + )) + .with_field(field( + "title", + "title", + String::describe(ctx), + "crates/trade/src/listing/validation.rs", + 29, + )) + .with_field(field( + "description", + "description", + String::describe(ctx), + "crates/trade/src/listing/validation.rs", + 30, + )) + .with_field(field( + "product_type", + "product_type", + String::describe(ctx), + "crates/trade/src/listing/validation.rs", + 31, + )) + .with_field(field( + "primary_bin_id", + "primary_bin_id", + String::describe(ctx), + "crates/trade/src/listing/validation.rs", + 32, + )) + .with_field(field( + "bin_quantity", + "bin_quantity", + ts_ref("RadrootsCoreQuantity"), + "crates/trade/src/listing/validation.rs", + 33, + )) + .with_field(field( + "unit", + "unit", + ts_ref("RadrootsCoreUnit"), + "crates/trade/src/listing/validation.rs", + 34, + )) + .with_field(field( + "unit_price", + "unit_price", + ts_ref("RadrootsCoreMoney"), + "crates/trade/src/listing/validation.rs", + 35, + )) + .with_field(field( + "inventory_available", + "inventory_available", + ts_ref("RadrootsCoreDecimal"), + "crates/trade/src/listing/validation.rs", + 36, + )) + .with_field(field( + "availability", + "availability", + ts_ref("RadrootsListingAvailability"), + "crates/trade/src/listing/validation.rs", + 37, + )) + .with_field(field( + "location", + "location", + ts_ref("RadrootsListingLocation"), + "crates/trade/src/listing/validation.rs", + 38, + )) + .with_field(field( + "delivery_method", + "delivery_method", + ts_ref("RadrootsListingDeliveryMethod"), + "crates/trade/src/listing/validation.rs", + 39, + )) + .with_field(field( + "listing", + "listing", + ts_ref("RadrootsListing"), + "crates/trade/src/listing/validation.rs", + 40, + )); + register(ctx, "RadrootsTradeListing", TypeDef::Struct(def)) + } +} + +impl Dto for RadrootsTradeListingSubtotal { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + trade_listing_total_like( + ctx, + "RadrootsTradeListingSubtotal", + "crates/trade/src/listing/model.rs", + 3, + ) + } +} + +impl Dto for RadrootsTradeListingTotal { + fn describe(ctx: &mut DescribeCtx) -> TypeRef { + trade_listing_total_like( + ctx, + "RadrootsTradeListingTotal", + "crates/trade/src/listing/model.rs", + 12, + ) + } +} + +fn trade_listing_total_like( + ctx: &mut DescribeCtx, + rust_ident: &str, + file: &str, + line: u32, +) -> TypeRef { + let def = StructDef::new(rust_ident, rust_ident, span(file, line)) + .with_field(field( + "price_amount", + "price_amount", + ts_ref("RadrootsCoreMoney"), + file, + line + 1, + )) + .with_field(field( + "price_currency", + "price_currency", + ts_ref("RadrootsCoreCurrency"), + file, + line + 2, + )) + .with_field(field( + "quantity_amount", + "quantity_amount", + ts_ref("RadrootsCoreDecimal"), + file, + line + 3, + )) + .with_field(field( + "quantity_unit", + "quantity_unit", + ts_ref("RadrootsCoreUnit"), + file, + line + 4, + )); + register(ctx, rust_ident, TypeDef::Struct(def)) +} + +fn register(ctx: &mut DescribeCtx, rust_ident: &str, type_def: TypeDef) -> TypeRef { + ctx.register_type(RustTypeId::new("radroots_trade", rust_ident), type_def) +} + +fn ts_ref(target_type: &str) -> TypeRef { + TypeRef::Override(TargetOverride::new(BackendId::TypeScript, target_type)) +} + +fn field(rust_name: &str, wire_name: &str, ty: TypeRef, file: &str, line: u32) -> FieldDef { + FieldDef::new( + IdentName::new(rust_name), + WireFieldNames::same(wire_name), + TargetFieldNames::new(wire_name, rust_name), + ty, + span(file, line), + ) +} + +fn span(file: &str, line: u32) -> SourceSpan { + SourceSpan::new(file, line, 1) +} + +#[cfg(test)] +mod tests { + use dto_bindgen_core::{BackendId, Registry, StructDef, TypeDef, TypeRef, build_registry}; + + use super::dto_roots; + + const TRADE_SOURCE_ROOTS: &[&str] = &[ + "RadrootsTradeListing", + "RadrootsTradeListingSubtotal", + "RadrootsTradeListingTotal", + ]; + + #[test] + fn trade_descriptor_roots_build_registry() { + let registry = build_registry(dto_roots()); + + assert!( + !registry.has_errors(), + "trade registry has diagnostics: {:?}", + registry.diagnostics + ); + assert_eq!(registry.roots.len(), dto_roots().len()); + } + + #[test] + fn trade_source_roots_are_deterministic() { + let registry = build_registry(dto_roots()); + + assert_eq!(root_export_names(&registry), TRADE_SOURCE_ROOTS); + } + + #[test] + fn trade_source_fields_use_package_aliases_for_import_boundaries() { + let registry = build_registry(dto_roots()); + let listing = find_struct(&registry, "RadrootsTradeListing"); + let subtotal = find_struct(&registry, "RadrootsTradeListingSubtotal"); + + assert_eq!( + typescript_override_target(field_ty(listing, "inventory_available")), + Some("RadrootsCoreDecimal") + ); + assert_eq!( + typescript_override_target(field_ty(listing, "listing")), + Some("RadrootsListing") + ); + assert_eq!( + typescript_override_target(field_ty(subtotal, "price_currency")), + Some("RadrootsCoreCurrency") + ); + } + + fn root_export_names(registry: &Registry) -> Vec<&str> { + registry + .roots + .iter() + .map(|type_id| { + registry + .type_def(*type_id) + .map(type_export_name) + .expect("root type") + }) + .collect() + } + + fn type_export_name(def: &TypeDef) -> &str { + match def { + TypeDef::Struct(def) => def.export_name.as_str(), + TypeDef::Enum(def) => def.export_name.as_str(), + } + } + + fn find_struct<'a>(registry: &'a Registry, export_name: &str) -> &'a StructDef { + registry + .types_by_id + .values() + .find_map(|def| match def { + TypeDef::Struct(def) if def.export_name == export_name => Some(def), + _ => None, + }) + .expect("descriptor struct") + } + + fn field_ty<'a>(def: &'a StructDef, field_name: &str) -> &'a TypeRef { + &def.fields + .iter() + .find(|field| field.target.typescript == field_name) + .expect("descriptor field") + .ty + } + + fn typescript_override_target(ty: &TypeRef) -> Option<&str> { + match ty { + TypeRef::Override(target) if target.backend == BackendId::TypeScript => { + Some(target.target_type.as_str()) + } + _ => None, + } + } +} diff --git a/crates/trade/src/lib.rs b/crates/trade/src/lib.rs @@ -3,6 +3,8 @@ #[cfg(not(feature = "std"))] extern crate alloc; +#[cfg(feature = "dto-bindgen")] +pub mod dto; pub mod listing; pub mod order; pub mod prelude;