cli

Command-line interface for Radroots
git clone https://radroots.dev/git/cli.git
Log | Files | Refs | README | LICENSE

target.rs (12892B)


      1 use serde::Serialize;
      2 use serde_json::Value;
      3 
      4 use super::context::OperationContext;
      5 use super::error::OperationAdapterError;
      6 use super::request::{
      7     OperationData, OperationRequest, OperationRequestData, OperationRequestPayload,
      8 };
      9 use super::result::{OperationResult, OperationResultData, OperationResultPayload, value_to_data};
     10 use crate::cli::TargetCliArgs;
     11 use crate::registry::{OPERATION_REGISTRY, OperationSpec};
     12 
     13 macro_rules! target_operation_contracts {
     14     ($( $variant:ident => ($request:ident, $result:ident, $operation_id:literal) ),+ $(,)?) => {
     15         #[derive(Debug, Clone, PartialEq)]
     16         pub enum TargetOperationRequest {
     17             $( $variant(OperationRequest<$request>), )+
     18         }
     19 
     20         impl TargetOperationRequest {
     21             pub fn from_target_args(args: &TargetCliArgs) -> Result<Self, OperationAdapterError> {
     22                 Self::from_operation_id_with_input(
     23                     crate::cli::input::operation_id_from_target(args),
     24                     OperationContext::from_target_args(args),
     25                     crate::cli::input::target_operation_input(&args.command),
     26                 )
     27             }
     28 
     29             pub fn from_operation_id(
     30                 operation_id: &'static str,
     31                 context: OperationContext,
     32             ) -> Result<Self, OperationAdapterError> {
     33                 Self::from_operation_id_with_input(operation_id, context, OperationData::new())
     34             }
     35 
     36             fn from_operation_id_with_input(
     37                 operation_id: &'static str,
     38                 context: OperationContext,
     39                 input: OperationData,
     40             ) -> Result<Self, OperationAdapterError> {
     41                 match operation_id {
     42                     $( $operation_id => Ok(Self::$variant(OperationRequest::new(context, $request::from_data(input))?)), )+
     43                     _ => Err(OperationAdapterError::UnknownOperation(operation_id.to_owned())),
     44                 }
     45             }
     46 
     47             pub fn operation_id(&self) -> &'static str {
     48                 match self {
     49                     $( Self::$variant(request) => request.operation_id(), )+
     50                 }
     51             }
     52 
     53             pub fn spec(&self) -> &'static OperationSpec {
     54                 match self {
     55                     $( Self::$variant(request) => request.spec, )+
     56                 }
     57             }
     58 
     59             pub fn context(&self) -> &OperationContext {
     60                 match self {
     61                     $( Self::$variant(request) => &request.context, )+
     62                 }
     63             }
     64 
     65             pub fn request_type_name(&self) -> &'static str {
     66                 match self {
     67                     $( Self::$variant(request) => request.request_type_name(), )+
     68                 }
     69             }
     70 
     71             pub fn request_type_for_operation(operation_id: &str) -> Option<&'static str> {
     72                 match operation_id {
     73                     $( $operation_id => Some(stringify!($request)), )+
     74                     _ => None,
     75                 }
     76             }
     77         }
     78 
     79         #[derive(Debug, Clone, PartialEq)]
     80         pub enum TargetOperationResult {
     81             $( $variant(OperationResult<$result>), )+
     82         }
     83 
     84         impl TargetOperationResult {
     85             pub fn operation_id(&self) -> &'static str {
     86                 match self {
     87                     $( Self::$variant(result) => result.operation_id(), )+
     88                 }
     89             }
     90 
     91             pub fn result_type_name(&self) -> &'static str {
     92                 match self {
     93                     $( Self::$variant(result) => result.result_type_name(), )+
     94                 }
     95             }
     96 
     97             pub fn result_type_for_operation(operation_id: &str) -> Option<&'static str> {
     98                 match operation_id {
     99                     $( $operation_id => Some(stringify!($result)), )+
    100                     _ => None,
    101                 }
    102             }
    103         }
    104 
    105         $(
    106             #[derive(Debug, Default, Clone, PartialEq, Serialize)]
    107             pub struct $request {
    108                 #[serde(flatten)]
    109                 pub input: OperationData,
    110             }
    111 
    112             impl $request {
    113                 pub fn from_data(input: OperationData) -> Self {
    114                     Self { input }
    115                 }
    116             }
    117 
    118             impl OperationRequestPayload for $request {
    119                 const OPERATION_ID: &'static str = $operation_id;
    120                 const REQUEST_TYPE: &'static str = stringify!($request);
    121             }
    122 
    123             impl OperationRequestData for $request {
    124                 fn input(&self) -> &OperationData {
    125                     &self.input
    126                 }
    127             }
    128 
    129             #[derive(Debug, Default, Clone, PartialEq, Serialize)]
    130             pub struct $result {
    131                 #[serde(flatten)]
    132                 pub data: OperationData,
    133             }
    134 
    135             impl $result {
    136                 pub fn from_data(data: OperationData) -> Self {
    137                     Self { data }
    138                 }
    139 
    140                 pub fn from_value(value: Value) -> Self {
    141                     Self {
    142                         data: value_to_data(value),
    143                     }
    144                 }
    145 
    146                 pub fn from_serializable<T: Serialize>(
    147                     value: &T,
    148                 ) -> Result<Self, OperationAdapterError> {
    149                     Ok(Self::from_value(
    150                         serde_json::to_value(value)
    151                             .map_err(|error| OperationAdapterError::Serialization(error.to_string()))?,
    152                     ))
    153                 }
    154             }
    155 
    156             impl OperationResultPayload for $result {
    157                 const OPERATION_ID: &'static str = $operation_id;
    158                 const RESULT_TYPE: &'static str = stringify!($result);
    159             }
    160 
    161             impl OperationResultData for $result {
    162                 fn from_data(data: OperationData) -> Self {
    163                     Self { data }
    164                 }
    165             }
    166         )+
    167     };
    168 }
    169 
    170 target_operation_contracts! {
    171     WorkspaceInit => (WorkspaceInitRequest, WorkspaceInitResult, "workspace.init"),
    172     WorkspaceGet => (WorkspaceGetRequest, WorkspaceGetResult, "workspace.get"),
    173     HealthStatusGet => (HealthStatusGetRequest, HealthStatusGetResult, "health.status.get"),
    174     HealthCheckRun => (HealthCheckRunRequest, HealthCheckRunResult, "health.check.run"),
    175     ConfigGet => (ConfigGetRequest, ConfigGetResult, "config.get"),
    176     AccountCreate => (AccountCreateRequest, AccountCreateResult, "account.create"),
    177     AccountImport => (AccountImportRequest, AccountImportResult, "account.import"),
    178     AccountAttachSecret => (AccountAttachSecretRequest, AccountAttachSecretResult, "account.attach_secret"),
    179     AccountGet => (AccountGetRequest, AccountGetResult, "account.get"),
    180     AccountList => (AccountListRequest, AccountListResult, "account.list"),
    181     AccountRemove => (AccountRemoveRequest, AccountRemoveResult, "account.remove"),
    182     AccountSelectionGet => (AccountSelectionGetRequest, AccountSelectionGetResult, "account.selection.get"),
    183     AccountSelectionUpdate => (AccountSelectionUpdateRequest, AccountSelectionUpdateResult, "account.selection.update"),
    184     AccountSelectionClear => (AccountSelectionClearRequest, AccountSelectionClearResult, "account.selection.clear"),
    185     SignerStatusGet => (SignerStatusGetRequest, SignerStatusGetResult, "signer.status.get"),
    186     RelayList => (RelayListRequest, RelayListResult, "relay.list"),
    187     StoreInit => (StoreInitRequest, StoreInitResult, "store.init"),
    188     StoreStatusGet => (StoreStatusGetRequest, StoreStatusGetResult, "store.status.get"),
    189     StoreExport => (StoreExportRequest, StoreExportResult, "store.export"),
    190     StoreBackupCreate => (StoreBackupCreateRequest, StoreBackupCreateResult, "store.backup.create"),
    191     StoreBackupRestore => (StoreBackupRestoreRequest, StoreBackupRestoreResult, "store.backup.restore"),
    192     SyncStatusGet => (SyncStatusGetRequest, SyncStatusGetResult, "sync.status.get"),
    193     SyncPull => (SyncPullRequest, SyncPullResult, "sync.pull"),
    194     SyncPush => (SyncPushRequest, SyncPushResult, "sync.push"),
    195     SyncWatch => (SyncWatchRequest, SyncWatchResult, "sync.watch"),
    196     FarmCreate => (FarmCreateRequest, FarmCreateResult, "farm.create"),
    197     FarmGet => (FarmGetRequest, FarmGetResult, "farm.get"),
    198     FarmRebind => (FarmRebindRequest, FarmRebindResult, "farm.rebind"),
    199     FarmProfileUpdate => (FarmProfileUpdateRequest, FarmProfileUpdateResult, "farm.profile.update"),
    200     FarmLocationUpdate => (FarmLocationUpdateRequest, FarmLocationUpdateResult, "farm.location.update"),
    201     FarmFulfillmentUpdate => (FarmFulfillmentUpdateRequest, FarmFulfillmentUpdateResult, "farm.fulfillment.update"),
    202     FarmReadinessCheck => (FarmReadinessCheckRequest, FarmReadinessCheckResult, "farm.readiness.check"),
    203     FarmPublish => (FarmPublishRequest, FarmPublishResult, "farm.publish"),
    204     ListingCreate => (ListingCreateRequest, ListingCreateResult, "listing.create"),
    205     ListingGet => (ListingGetRequest, ListingGetResult, "listing.get"),
    206     ListingList => (ListingListRequest, ListingListResult, "listing.list"),
    207     ListingAppList => (ListingAppListRequest, ListingAppListResult, "listing.app.list"),
    208     ListingAppExport => (ListingAppExportRequest, ListingAppExportResult, "listing.app.export"),
    209     ListingUpdate => (ListingUpdateRequest, ListingUpdateResult, "listing.update"),
    210     ListingValidate => (ListingValidateRequest, ListingValidateResult, "listing.validate"),
    211     ListingRebind => (ListingRebindRequest, ListingRebindResult, "listing.rebind"),
    212     ListingPublish => (ListingPublishRequest, ListingPublishResult, "listing.publish"),
    213     ListingArchive => (ListingArchiveRequest, ListingArchiveResult, "listing.archive"),
    214     MarketRefresh => (MarketRefreshRequest, MarketRefreshResult, "market.refresh"),
    215     MarketProductSearch => (MarketProductSearchRequest, MarketProductSearchResult, "market.product.search"),
    216     MarketListingGet => (MarketListingGetRequest, MarketListingGetResult, "market.listing.get"),
    217     BasketCreate => (BasketCreateRequest, BasketCreateResult, "basket.create"),
    218     BasketGet => (BasketGetRequest, BasketGetResult, "basket.get"),
    219     BasketList => (BasketListRequest, BasketListResult, "basket.list"),
    220     BasketItemAdd => (BasketItemAddRequest, BasketItemAddResult, "basket.item.add"),
    221     BasketItemUpdate => (BasketItemUpdateRequest, BasketItemUpdateResult, "basket.item.update"),
    222     BasketItemRemove => (BasketItemRemoveRequest, BasketItemRemoveResult, "basket.item.remove"),
    223     BasketAdjustmentAdd => (BasketAdjustmentAddRequest, BasketAdjustmentAddResult, "basket.adjustment.add"),
    224     BasketAdjustmentRemove => (BasketAdjustmentRemoveRequest, BasketAdjustmentRemoveResult, "basket.adjustment.remove"),
    225     BasketValidate => (BasketValidateRequest, BasketValidateResult, "basket.validate"),
    226     BasketQuoteCreate => (BasketQuoteCreateRequest, BasketQuoteCreateResult, "basket.quote.create"),
    227     OrderSubmit => (OrderSubmitRequest, OrderSubmitResult, "order.submit"),
    228     OrderGet => (OrderGetRequest, OrderGetResult, "order.get"),
    229     OrderList => (OrderListRequest, OrderListResult, "order.list"),
    230     OrderAppList => (OrderAppListRequest, OrderAppListResult, "order.app.list"),
    231     OrderAppExport => (OrderAppExportRequest, OrderAppExportResult, "order.app.export"),
    232     OrderRebind => (OrderRebindRequest, OrderRebindResult, "order.rebind"),
    233     OrderAccept => (OrderAcceptRequest, OrderAcceptResult, "order.accept"),
    234     OrderDecline => (OrderDeclineRequest, OrderDeclineResult, "order.decline"),
    235     OrderCancel => (OrderCancelRequest, OrderCancelResult, "order.cancel"),
    236     OrderRevisionPropose => (OrderRevisionProposeRequest, OrderRevisionProposeResult, "order.revision.propose"),
    237     OrderRevisionAccept => (OrderRevisionAcceptRequest, OrderRevisionAcceptResult, "order.revision.accept"),
    238     OrderRevisionDecline => (OrderRevisionDeclineRequest, OrderRevisionDeclineResult, "order.revision.decline"),
    239     OrderStatusGet => (OrderStatusGetRequest, OrderStatusGetResult, "order.status.get"),
    240     OrderEventList => (OrderEventListRequest, OrderEventListResult, "order.event.list"),
    241     OrderEventWatch => (OrderEventWatchRequest, OrderEventWatchResult, "order.event.watch"),
    242     ValidationReceiptGet => (ValidationReceiptGetRequest, ValidationReceiptGetResult, "validation.receipt.get"),
    243     ValidationReceiptList => (ValidationReceiptListRequest, ValidationReceiptListResult, "validation.receipt.list"),
    244     ValidationReceiptVerify => (ValidationReceiptVerifyRequest, ValidationReceiptVerifyResult, "validation.receipt.verify"),
    245 }
    246 
    247 pub fn adapter_registry_linkage_is_valid() -> bool {
    248     OPERATION_REGISTRY.iter().all(|operation| {
    249         TargetOperationRequest::request_type_for_operation(operation.operation_id)
    250             == Some(operation.rust_request)
    251             && TargetOperationResult::result_type_for_operation(operation.operation_id)
    252                 == Some(operation.rust_result)
    253     })
    254 }