Skip to main content

pethost/
json.rs

1// @generated by protoc-gen-panel-rust from v1/panel.proto. DO NOT EDIT.
2
3//! The API's JSON, for every message and enum of [`types`](crate::types) and for a time: what
4//! the API takes and answers over HTTP, and what its reference documents.
5//!
6//! No field's name and no value's form is written here. A value crosses to the wire layer's
7//! type (convert.rs), and that layer's own JSON writes it; reading is the same way back. The
8//! wire layer was generated with the proto's field names as its JSON names (the SDK's
9//! buf.gen.yaml), so its JSON is the API's.
10
11use serde::de::value::{MapDeserializer, SeqDeserializer};
12use serde::de::{DeserializeOwned, Error as _, IntoDeserializer, Unexpected, Visitor};
13use serde::{Deserialize, Deserializer, Serialize, Serializer};
14use serde_json::Value;
15
16use crate::proto::pethost::panel::v1 as wire;
17use crate::{convert, timestamp, types};
18
19/// The two impls of a public type: `$to` makes the wire layer's type of it, whose JSON is
20/// written, and `$from` makes it of the one that was read.
21macro_rules! json {
22    ($public:ty, $wire:ty, $to:path, $from:path) => {
23        /// As the API's JSON: the proto's field names, an enum as its value's name, a 64-bit
24        /// integer as a string, a time as RFC 3339, bytes as base64.
25        impl Serialize for $public {
26            fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
27                $to(Clone::clone(self)).serialize(serializer)
28            }
29        }
30
31        /// From the API's JSON. A field this version does not know is refused, as the API
32        /// refuses one it does not have.
33        impl<'de> Deserialize<'de> for $public {
34            fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
35                read::<$wire, D>(deserializer).map($from)
36            }
37        }
38    };
39}
40
41json!(
42    crate::Timestamp,
43    buffa_types::google::protobuf::Timestamp,
44    timestamp::to_wire,
45    timestamp::from_wire
46);
47
48json!(
49    types::AlertChannelKind,
50    buffa::EnumValue<wire::AlertChannelKind>,
51    convert::alert_channel_kind_to_wire,
52    convert::alert_channel_kind_from_wire
53);
54json!(
55    types::MachineSessionKind,
56    buffa::EnumValue<wire::MachineSessionKind>,
57    convert::machine_session_kind_to_wire,
58    convert::machine_session_kind_from_wire
59);
60json!(
61    types::ProjectProblemKind,
62    buffa::EnumValue<wire::ProjectProblemKind>,
63    convert::project_problem_kind_to_wire,
64    convert::project_problem_kind_from_wire
65);
66json!(
67    types::ServicesActionKind,
68    buffa::EnumValue<wire::ServicesActionKind>,
69    convert::services_action_kind_to_wire,
70    convert::services_action_kind_from_wire
71);
72json!(
73    types::ServiceState,
74    buffa::EnumValue<wire::ServiceState>,
75    convert::service_state_to_wire,
76    convert::service_state_from_wire
77);
78json!(
79    types::RestartPolicy,
80    buffa::EnumValue<wire::RestartPolicy>,
81    convert::restart_policy_to_wire,
82    convert::restart_policy_from_wire
83);
84json!(
85    types::HealthStatus,
86    buffa::EnumValue<wire::HealthStatus>,
87    convert::health_status_to_wire,
88    convert::health_status_from_wire
89);
90json!(
91    types::CertificateSource,
92    buffa::EnumValue<wire::CertificateSource>,
93    convert::certificate_source_to_wire,
94    convert::certificate_source_from_wire
95);
96json!(
97    types::OperationKind,
98    buffa::EnumValue<wire::OperationKind>,
99    convert::operation_kind_to_wire,
100    convert::operation_kind_from_wire
101);
102json!(
103    types::OperationStatus,
104    buffa::EnumValue<wire::OperationStatus>,
105    convert::operation_status_to_wire,
106    convert::operation_status_from_wire
107);
108json!(
109    types::DeployFailureReason,
110    buffa::EnumValue<wire::DeployFailureReason>,
111    convert::deploy_failure_reason_to_wire,
112    convert::deploy_failure_reason_from_wire
113);
114json!(
115    types::DatabaseEngine,
116    buffa::EnumValue<wire::DatabaseEngine>,
117    convert::database_engine_to_wire,
118    convert::database_engine_from_wire
119);
120json!(
121    types::TrafficMetric,
122    buffa::EnumValue<wire::TrafficMetric>,
123    convert::traffic_metric_to_wire,
124    convert::traffic_metric_from_wire
125);
126json!(
127    types::AlertStatus,
128    buffa::EnumValue<wire::AlertStatus>,
129    convert::alert_status_to_wire,
130    convert::alert_status_from_wire
131);
132json!(
133    types::IncidentQuietReason,
134    buffa::EnumValue<wire::IncidentQuietReason>,
135    convert::incident_quiet_reason_to_wire,
136    convert::incident_quiet_reason_from_wire
137);
138json!(
139    types::OutputStream,
140    buffa::EnumValue<wire::OutputStream>,
141    convert::output_stream_to_wire,
142    convert::output_stream_from_wire
143);
144json!(
145    types::FileType,
146    buffa::EnumValue<wire::FileType>,
147    convert::file_type_to_wire,
148    convert::file_type_from_wire
149);
150json!(
151    types::FileLocation,
152    buffa::EnumValue<wire::FileLocation>,
153    convert::file_location_to_wire,
154    convert::file_location_from_wire
155);
156json!(
157    types::DatabaseLinkRefusalReason,
158    buffa::EnumValue<wire::DatabaseLinkRefusalReason>,
159    convert::database_link_refusal_reason_to_wire,
160    convert::database_link_refusal_reason_from_wire
161);
162json!(
163    types::NoMachineReason,
164    buffa::EnumValue<wire::NoMachineReason>,
165    convert::no_machine_reason_to_wire,
166    convert::no_machine_reason_from_wire
167);
168
169json!(
170    types::GetMachineRequest,
171    wire::GetMachineRequest,
172    wire::GetMachineRequest::from,
173    types::GetMachineRequest::from
174);
175json!(
176    types::GetMachineResponse,
177    wire::GetMachineResponse,
178    wire::GetMachineResponse::from,
179    types::GetMachineResponse::from
180);
181json!(types::Machine, wire::Machine, wire::Machine::from, types::Machine::from);
182json!(
183    types::AlertDestination,
184    wire::AlertDestination,
185    wire::AlertDestination::from,
186    types::AlertDestination::from
187);
188json!(
189    types::MachineSession,
190    wire::MachineSession,
191    wire::MachineSession::from,
192    types::MachineSession::from
193);
194json!(
195    types::DiskUsage,
196    wire::DiskUsage,
197    wire::DiskUsage::from,
198    types::DiskUsage::from
199);
200json!(types::SshKey, wire::SshKey, wire::SshKey::from, types::SshKey::from);
201json!(
202    types::GithubConnection,
203    wire::GithubConnection,
204    wire::GithubConnection::from,
205    types::GithubConnection::from
206);
207json!(
208    types::GithubRepository,
209    wire::GithubRepository,
210    wire::GithubRepository::from,
211    types::GithubRepository::from
212);
213json!(
214    types::DeletedProject,
215    wire::DeletedProject,
216    wire::DeletedProject::from,
217    types::DeletedProject::from
218);
219json!(
220    types::RunMachineActionRequest,
221    wire::RunMachineActionRequest,
222    wire::RunMachineActionRequest::from,
223    types::RunMachineActionRequest::from
224);
225json!(
226    types::RestartMachineAction,
227    wire::RestartMachineAction,
228    wire::RestartMachineAction::from,
229    types::RestartMachineAction::from
230);
231json!(
232    types::RunMachineActionResponse,
233    wire::RunMachineActionResponse,
234    wire::RunMachineActionResponse::from,
235    types::RunMachineActionResponse::from
236);
237json!(
238    types::ProjectMetadata,
239    wire::ProjectMetadata,
240    wire::ProjectMetadata::from,
241    types::ProjectMetadata::from
242);
243json!(
244    types::ProjectSummary,
245    wire::ProjectSummary,
246    wire::ProjectSummary::from,
247    types::ProjectSummary::from
248);
249json!(
250    types::ServiceSummary,
251    wire::ServiceSummary,
252    wire::ServiceSummary::from,
253    types::ServiceSummary::from
254);
255json!(
256    types::ProjectProblem,
257    wire::ProjectProblem,
258    wire::ProjectProblem::from,
259    types::ProjectProblem::from
260);
261json!(
262    types::GetProjectRequest,
263    wire::GetProjectRequest,
264    wire::GetProjectRequest::from,
265    types::GetProjectRequest::from
266);
267json!(
268    types::GetProjectResponse,
269    wire::GetProjectResponse,
270    wire::GetProjectResponse::from,
271    types::GetProjectResponse::from
272);
273json!(types::Project, wire::Project, wire::Project::from, types::Project::from);
274json!(
275    types::RunningServicesAction,
276    wire::RunningServicesAction,
277    wire::RunningServicesAction::from,
278    types::RunningServicesAction::from
279);
280json!(
281    types::ProjectSource,
282    wire::ProjectSource,
283    wire::ProjectSource::from,
284    types::ProjectSource::from
285);
286json!(
287    types::GithubSource,
288    wire::GithubSource,
289    wire::GithubSource::from,
290    types::GithubSource::from
291);
292json!(
293    types::GithubCommit,
294    wire::GithubCommit,
295    wire::GithubCommit::from,
296    types::GithubCommit::from
297);
298json!(types::Service, wire::Service, wire::Service::from, types::Service::from);
299json!(
300    types::PublishedPort,
301    wire::PublishedPort,
302    wire::PublishedPort::from,
303    types::PublishedPort::from
304);
305json!(
306    types::VolumeMount,
307    wire::VolumeMount,
308    wire::VolumeMount::from,
309    types::VolumeMount::from
310);
311json!(
312    types::HealthCheck,
313    wire::HealthCheck,
314    wire::HealthCheck::from,
315    types::HealthCheck::from
316);
317json!(
318    types::EnvironmentVariable,
319    wire::EnvironmentVariable,
320    wire::EnvironmentVariable::from,
321    types::EnvironmentVariable::from
322);
323json!(types::Volume, wire::Volume, wire::Volume::from, types::Volume::from);
324json!(
325    types::VolumeMountedBy,
326    wire::VolumeMountedBy,
327    wire::VolumeMountedBy::from,
328    types::VolumeMountedBy::from
329);
330json!(types::Host, wire::Host, wire::Host::from, types::Host::from);
331json!(types::Route, wire::Route, wire::Route::from, types::Route::from);
332json!(
333    types::Operation,
334    wire::Operation,
335    wire::Operation::from,
336    types::Operation::from
337);
338json!(
339    types::Snapshot,
340    wire::Snapshot,
341    wire::Snapshot::from,
342    types::Snapshot::from
343);
344json!(
345    types::HttpTrafficSummary,
346    wire::HttpTrafficSummary,
347    wire::HttpTrafficSummary::from,
348    types::HttpTrafficSummary::from
349);
350json!(
351    types::CreateProjectRequest,
352    wire::CreateProjectRequest,
353    wire::CreateProjectRequest::from,
354    types::CreateProjectRequest::from
355);
356json!(
357    types::CreateProjectResponse,
358    wire::CreateProjectResponse,
359    wire::CreateProjectResponse::from,
360    types::CreateProjectResponse::from
361);
362json!(
363    types::DeployProjectRequest,
364    wire::DeployProjectRequest,
365    wire::DeployProjectRequest::from,
366    types::DeployProjectRequest::from
367);
368json!(
369    types::MountVolume,
370    wire::MountVolume,
371    wire::MountVolume::from,
372    types::MountVolume::from
373);
374json!(
375    types::ProjectExtension,
376    wire::ProjectExtension,
377    wire::ProjectExtension::from,
378    types::ProjectExtension::from
379);
380json!(
381    types::FileChange,
382    wire::FileChange,
383    wire::FileChange::from,
384    types::FileChange::from
385);
386json!(
387    types::DeployProjectResponse,
388    wire::DeployProjectResponse,
389    wire::DeployProjectResponse::from,
390    types::DeployProjectResponse::from
391);
392json!(
393    types::SpecViolation,
394    wire::SpecViolation,
395    wire::SpecViolation::from,
396    types::SpecViolation::from
397);
398json!(
399    types::ListCommitsRequest,
400    wire::ListCommitsRequest,
401    wire::ListCommitsRequest::from,
402    types::ListCommitsRequest::from
403);
404json!(
405    types::ListCommitsResponse,
406    wire::ListCommitsResponse,
407    wire::ListCommitsResponse::from,
408    types::ListCommitsResponse::from
409);
410json!(
411    types::BranchCommit,
412    wire::BranchCommit,
413    wire::BranchCommit::from,
414    types::BranchCommit::from
415);
416json!(
417    types::RunProjectActionRequest,
418    wire::RunProjectActionRequest,
419    wire::RunProjectActionRequest::from,
420    types::RunProjectActionRequest::from
421);
422json!(
423    types::ServicesAction,
424    wire::ServicesAction,
425    wire::ServicesAction::from,
426    types::ServicesAction::from
427);
428json!(
429    types::RecreateServiceAction,
430    wire::RecreateServiceAction,
431    wire::RecreateServiceAction::from,
432    types::RecreateServiceAction::from
433);
434json!(
435    types::BackUpAction,
436    wire::BackUpAction,
437    wire::BackUpAction::from,
438    types::BackUpAction::from
439);
440json!(
441    types::RestoreSnapshotAction,
442    wire::RestoreSnapshotAction,
443    wire::RestoreSnapshotAction::from,
444    types::RestoreSnapshotAction::from
445);
446json!(
447    types::CancelOperationAction,
448    wire::CancelOperationAction,
449    wire::CancelOperationAction::from,
450    types::CancelOperationAction::from
451);
452json!(
453    types::DeleteProjectAction,
454    wire::DeleteProjectAction,
455    wire::DeleteProjectAction::from,
456    types::DeleteProjectAction::from
457);
458json!(
459    types::RunProjectActionResponse,
460    wire::RunProjectActionResponse,
461    wire::RunProjectActionResponse::from,
462    types::RunProjectActionResponse::from
463);
464json!(
465    types::Database,
466    wire::Database,
467    wire::Database::from,
468    types::Database::from
469);
470json!(
471    types::DatabaseConnection,
472    wire::DatabaseConnection,
473    wire::DatabaseConnection::from,
474    types::DatabaseConnection::from
475);
476json!(
477    types::DatabaseSummary,
478    wire::DatabaseSummary,
479    wire::DatabaseSummary::from,
480    types::DatabaseSummary::from
481);
482json!(
483    types::DatabaseEngineOffer,
484    wire::DatabaseEngineOffer,
485    wire::DatabaseEngineOffer::from,
486    types::DatabaseEngineOffer::from
487);
488json!(
489    types::DatabaseSizeChoice,
490    wire::DatabaseSizeChoice,
491    wire::DatabaseSizeChoice::from,
492    types::DatabaseSizeChoice::from
493);
494json!(
495    types::LinkDatabaseRequest,
496    wire::LinkDatabaseRequest,
497    wire::LinkDatabaseRequest::from,
498    types::LinkDatabaseRequest::from
499);
500json!(
501    types::LinkDatabaseResponse,
502    wire::LinkDatabaseResponse,
503    wire::LinkDatabaseResponse::from,
504    types::LinkDatabaseResponse::from
505);
506json!(
507    types::SetProjectAlertsRequest,
508    wire::SetProjectAlertsRequest,
509    wire::SetProjectAlertsRequest::from,
510    types::SetProjectAlertsRequest::from
511);
512json!(
513    types::SetProjectAlertsResponse,
514    wire::SetProjectAlertsResponse,
515    wire::SetProjectAlertsResponse::from,
516    types::SetProjectAlertsResponse::from
517);
518json!(
519    types::SiteCheck,
520    wire::SiteCheck,
521    wire::SiteCheck::from,
522    types::SiteCheck::from
523);
524json!(
525    types::TrafficRule,
526    wire::TrafficRule,
527    wire::TrafficRule::from,
528    types::TrafficRule::from
529);
530json!(
531    types::ProjectAlerts,
532    wire::ProjectAlerts,
533    wire::ProjectAlerts::from,
534    types::ProjectAlerts::from
535);
536json!(
537    types::SiteCheckState,
538    wire::SiteCheckState,
539    wire::SiteCheckState::from,
540    types::SiteCheckState::from
541);
542json!(
543    types::SiteCheckResult,
544    wire::SiteCheckResult,
545    wire::SiteCheckResult::from,
546    types::SiteCheckResult::from
547);
548json!(
549    types::TrafficRuleState,
550    wire::TrafficRuleState,
551    wire::TrafficRuleState::from,
552    types::TrafficRuleState::from
553);
554json!(
555    types::Incident,
556    wire::Incident,
557    wire::Incident::from,
558    types::Incident::from
559);
560json!(
561    types::IncidentEvidence,
562    wire::IncidentEvidence,
563    wire::IncidentEvidence::from,
564    types::IncidentEvidence::from
565);
566json!(
567    types::UptimeDay,
568    wire::UptimeDay,
569    wire::UptimeDay::from,
570    types::UptimeDay::from
571);
572json!(
573    types::GetOperationRequest,
574    wire::GetOperationRequest,
575    wire::GetOperationRequest::from,
576    types::GetOperationRequest::from
577);
578json!(
579    types::GetOperationResponse,
580    wire::GetOperationResponse,
581    wire::GetOperationResponse::from,
582    types::GetOperationResponse::from
583);
584json!(
585    types::OperationLogLine,
586    wire::OperationLogLine,
587    wire::OperationLogLine::from,
588    types::OperationLogLine::from
589);
590json!(
591    types::HttpTrafficFilter,
592    wire::HttpTrafficFilter,
593    wire::HttpTrafficFilter::from,
594    types::HttpTrafficFilter::from
595);
596json!(
597    types::QueryHttpTrafficRequest,
598    wire::QueryHttpTrafficRequest,
599    wire::QueryHttpTrafficRequest::from,
600    types::QueryHttpTrafficRequest::from
601);
602json!(
603    types::QueryHttpTrafficResponse,
604    wire::QueryHttpTrafficResponse,
605    wire::QueryHttpTrafficResponse::from,
606    types::QueryHttpTrafficResponse::from
607);
608json!(
609    types::HttpTrafficBucket,
610    wire::HttpTrafficBucket,
611    wire::HttpTrafficBucket::from,
612    types::HttpTrafficBucket::from
613);
614json!(
615    types::HttpPathTraffic,
616    wire::HttpPathTraffic,
617    wire::HttpPathTraffic::from,
618    types::HttpPathTraffic::from
619);
620json!(
621    types::HttpRequest,
622    wire::HttpRequest,
623    wire::HttpRequest::from,
624    types::HttpRequest::from
625);
626json!(
627    types::ContainerLogFilter,
628    wire::ContainerLogFilter,
629    wire::ContainerLogFilter::from,
630    types::ContainerLogFilter::from
631);
632json!(
633    types::QueryContainerLogsRequest,
634    wire::QueryContainerLogsRequest,
635    wire::QueryContainerLogsRequest::from,
636    types::QueryContainerLogsRequest::from
637);
638json!(
639    types::QueryContainerLogsResponse,
640    wire::QueryContainerLogsResponse,
641    wire::QueryContainerLogsResponse::from,
642    types::QueryContainerLogsResponse::from
643);
644json!(types::LogLine, wire::LogLine, wire::LogLine::from, types::LogLine::from);
645json!(
646    types::RunServiceCommandRequest,
647    wire::RunServiceCommandRequest,
648    wire::RunServiceCommandRequest::from,
649    types::RunServiceCommandRequest::from
650);
651json!(
652    types::RunServiceCommandResponse,
653    wire::RunServiceCommandResponse,
654    wire::RunServiceCommandResponse::from,
655    types::RunServiceCommandResponse::from
656);
657json!(
658    types::FileEntry,
659    wire::FileEntry,
660    wire::FileEntry::from,
661    types::FileEntry::from
662);
663json!(
664    types::ReadPathRequest,
665    wire::ReadPathRequest,
666    wire::ReadPathRequest::from,
667    types::ReadPathRequest::from
668);
669json!(
670    types::ReadPathResponse,
671    wire::ReadPathResponse,
672    wire::ReadPathResponse::from,
673    types::ReadPathResponse::from
674);
675json!(
676    types::CreateTransferRequest,
677    wire::CreateTransferRequest,
678    wire::CreateTransferRequest::from,
679    types::CreateTransferRequest::from
680);
681json!(
682    types::ArchiveUpload,
683    wire::ArchiveUpload,
684    wire::ArchiveUpload::from,
685    types::ArchiveUpload::from
686);
687json!(
688    types::FileUpload,
689    wire::FileUpload,
690    wire::FileUpload::from,
691    types::FileUpload::from
692);
693json!(
694    types::PathDownload,
695    wire::PathDownload,
696    wire::PathDownload::from,
697    types::PathDownload::from
698);
699json!(
700    types::DatabaseDump,
701    wire::DatabaseDump,
702    wire::DatabaseDump::from,
703    types::DatabaseDump::from
704);
705json!(
706    types::CreateTransferResponse,
707    wire::CreateTransferResponse,
708    wire::CreateTransferResponse::from,
709    types::CreateTransferResponse::from
710);
711json!(
712    types::ProjectBusy,
713    wire::ProjectBusy,
714    wire::ProjectBusy::from,
715    types::ProjectBusy::from
716);
717json!(
718    types::ProjectChanged,
719    wire::ProjectChanged,
720    wire::ProjectChanged::from,
721    types::ProjectChanged::from
722);
723json!(
724    types::MachineUnreachable,
725    wire::MachineUnreachable,
726    wire::MachineUnreachable::from,
727    types::MachineUnreachable::from
728);
729json!(
730    types::MachineUpdatePending,
731    wire::MachineUpdatePending,
732    wire::MachineUpdatePending::from,
733    types::MachineUpdatePending::from
734);
735json!(
736    types::DatabaseLinkRefusal,
737    wire::DatabaseLinkRefusal,
738    wire::DatabaseLinkRefusal::from,
739    types::DatabaseLinkRefusal::from
740);
741json!(
742    types::NoMachine,
743    wire::NoMachine,
744    wire::NoMachine::from,
745    types::NoMachine::from
746);
747json!(
748    types::WatchOperationRequest,
749    wire::WatchOperationRequest,
750    wire::WatchOperationRequest::from,
751    types::WatchOperationRequest::from
752);
753json!(
754    types::WatchOperationResponse,
755    wire::WatchOperationResponse,
756    wire::WatchOperationResponse::from,
757    types::WatchOperationResponse::from
758);
759json!(
760    types::TailContainerLogsRequest,
761    wire::TailContainerLogsRequest,
762    wire::TailContainerLogsRequest::from,
763    types::TailContainerLogsRequest::from
764);
765json!(
766    types::TailContainerLogsResponse,
767    wire::TailContainerLogsResponse,
768    wire::TailContainerLogsResponse::from,
769    types::TailContainerLogsResponse::from
770);
771json!(
772    types::TailHttpTrafficRequest,
773    wire::TailHttpTrafficRequest,
774    wire::TailHttpTrafficRequest::from,
775    types::TailHttpTrafficRequest::from
776);
777json!(
778    types::TailHttpTrafficResponse,
779    wire::TailHttpTrafficResponse,
780    wire::TailHttpTrafficResponse::from,
781    types::TailHttpTrafficResponse::from
782);
783
784/// A value of the wire layer's, read from JSON as the API reads it.
785fn read<'de, Wire: DeserializeOwned, D: Deserializer<'de>>(deserializer: D) -> Result<Wire, D::Error> {
786    let value = Value::deserialize(deserializer)?;
787    Wire::deserialize(Strict { value, field: None }).map_err(D::Error::custom)
788}
789
790/// A JSON value as the wire layer reads it, with the name of the field it is the value of.
791///
792/// The wire layer passes over a field it does not know, where the API refuses one, so that a
793/// misspelled field cannot make a call that does something else. Passing over is asking the
794/// value to be ignored: here that is the refusal, and nothing else differs from reading the
795/// value itself.
796struct Strict {
797    value: Value,
798    field: Option<String>,
799}
800
801impl Strict {
802    fn item(value: Value) -> Self {
803        Self { value, field: None }
804    }
805
806    fn of_field((field, value): (String, Value)) -> (String, Self) {
807        let named = Self {
808            value,
809            field: Some(field.clone()),
810        };
811        (field, named)
812    }
813}
814
815impl<'de> IntoDeserializer<'de, serde_json::Error> for Strict {
816    type Deserializer = Self;
817
818    fn into_deserializer(self) -> Self {
819        self
820    }
821}
822
823impl<'de> Deserializer<'de> for Strict {
824    type Error = serde_json::Error;
825
826    fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
827        match self.value {
828            Value::Array(items) => {
829                let mut items = SeqDeserializer::<_, Self::Error>::new(items.into_iter().map(Self::item));
830                let read = visitor.visit_seq(&mut items)?;
831                items.end()?;
832                Ok(read)
833            }
834            Value::Object(fields) => {
835                let mut fields = MapDeserializer::<_, Self::Error>::new(fields.into_iter().map(Self::of_field));
836                let read = visitor.visit_map(&mut fields)?;
837                fields.end()?;
838                Ok(read)
839            }
840            scalar => scalar.deserialize_any(visitor),
841        }
842    }
843
844    fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
845        match self.value {
846            Value::Null => visitor.visit_none(),
847            _ => visitor.visit_some(self),
848        }
849    }
850
851    fn deserialize_newtype_struct<V: Visitor<'de>>(self, _: &'static str, visitor: V) -> Result<V::Value, Self::Error> {
852        visitor.visit_newtype_struct(self)
853    }
854
855    fn deserialize_struct<V: Visitor<'de>>(
856        self,
857        _: &'static str,
858        _: &'static [&'static str],
859        visitor: V,
860    ) -> Result<V::Value, Self::Error> {
861        match self.value {
862            // The wire layer would take a list as a message's fields in their order; the API
863            // takes a message as an object only.
864            Value::Array(_) => Err(Self::Error::invalid_type(Unexpected::Seq, &visitor)),
865            _ => self.deserialize_any(visitor),
866        }
867    }
868
869    fn deserialize_ignored_any<V: Visitor<'de>>(self, _: V) -> Result<V::Value, Self::Error> {
870        let field = self.field.unwrap_or_default();
871        Err(Self::Error::custom(format_args!("unknown field `{field}`")))
872    }
873
874    serde::forward_to_deserialize_any! {
875        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string bytes byte_buf unit
876        unit_struct seq tuple tuple_struct map enum identifier
877    }
878}