Skip to main content

printobserver_sdk/
contract.rs

1//! Generated by `contract-codegen` from the checked-in contract schemas.
2//!
3//! This file is the Rust client's request and response types.
4//!
5//! Do not edit by hand: change the contracts, regenerate with `just
6//! generate-clients`, and commit what that writes.
7
8use std::collections::BTreeMap;
9
10use serde::{Deserialize, Serialize};
11
12use crate::{Client, ClientError};
13
14/// The version of the server contract these types were generated from, which
15/// is the version the type crate declares in the tree they came from.
16pub const CONTRACT_VERSION: &str = "0.2.0";
17
18/// Every operation this client exposes a method for, which is every operation
19/// the server declares and no other.
20pub const OPERATION_NAMES: [&str; 16] = [
21    "status",
22    "context",
23    "image",
24    "history",
25    "manifest_get",
26    "manifest_set",
27    "pause",
28    "resume",
29    "cancel",
30    "start_print",
31    "set_feedrate_factor",
32    "set_flowrate_factor",
33    "set_tool_target_c",
34    "set_bed_target_c",
35    "set_fan_percent",
36    "acknowledge_failure",
37];
38
39/// What an operator's acknowledgement of a failure event asks for next.
40#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
41pub enum AcknowledgementDisposition {
42    /// Carry on printing.
43    #[serde(rename = "continue")]
44    Continue,
45    /// Carry on printing, watched more closely.
46    #[serde(rename = "watch")]
47    Watch,
48    /// Stop the print.
49    #[serde(rename = "stop")]
50    Stop,
51}
52
53/// What one mutating request left behind it.
54#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
55pub struct ActionAnswer {
56    /// The bounded intervention it opened, when it opened one.
57    #[serde(default, skip_serializing_if = "Option::is_none")]
58    pub intervention: Option<Intervention>,
59    /// What the printer said, when the request reached it and it refused.
60    #[serde(default, skip_serializing_if = "Option::is_none")]
61    pub printer_refusal: Option<String>,
62    /// The record of the request and the decision taken on it. A rejected
63    /// request's rejection is here, carrying its reason, the value asked for
64    /// and the range allowed, so a caller can ask again inside the range.
65    pub record: ActionRecord,
66}
67
68/// An accepted action reached the printer.
69#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
70pub struct ActionExecutedPayload {
71    /// The action's identifier.
72    pub action_id: ActionId,
73    /// The bounded intervention it opened, when it opened one.
74    #[serde(default, skip_serializing_if = "Option::is_none")]
75    pub intervention_id: Option<InterventionId>,
76}
77
78/// A lowercase hyphenated version 7 UUID identifying one requested action.
79pub type ActionId = String;
80
81/// One action of the closed vocabulary, named without its payload.
82///
83/// This is what a safety envelope grants and what a policy rejection names;
84/// the
85/// payload lives on `PrintAction` itself.
86#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
87pub enum ActionKind {
88    /// Pause the print.
89    #[serde(rename = "pause")]
90    Pause,
91    /// Resume the print.
92    #[serde(rename = "resume")]
93    Resume,
94    /// Cancel the print.
95    #[serde(rename = "cancel")]
96    Cancel,
97    /// Start a print of a named file.
98    #[serde(rename = "start_print")]
99    StartPrint,
100    /// Set the feedrate factor.
101    #[serde(rename = "set_feedrate_factor")]
102    SetFeedrateFactor,
103    /// Set the flowrate factor.
104    #[serde(rename = "set_flowrate_factor")]
105    SetFlowrateFactor,
106    /// Set a tool's target temperature.
107    #[serde(rename = "set_tool_target_c")]
108    SetToolTargetC,
109    /// Set the bed's target temperature.
110    #[serde(rename = "set_bed_target_c")]
111    SetBedTargetC,
112    /// Set the fan percentage.
113    #[serde(rename = "set_fan_percent")]
114    SetFanPercent,
115    /// Acknowledge a failure event.
116    #[serde(rename = "acknowledge_failure")]
117    AcknowledgeFailure,
118}
119
120/// One request, the decision taken on it, and what became of it.
121///
122/// `executed_at` and `outcome` are both optional and are absent together: a
123/// record is written when the decision is taken, which is before — and, for a
124/// rejected request, instead of — anything reaching the printer.
125#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
126pub struct ActionRecord {
127    /// The decision policy took on it.
128    pub decision: PolicyDecision,
129    /// When it reached the printer, if it did.
130    #[serde(default, skip_serializing_if = "Option::is_none")]
131    pub executed_at: Option<Timestamp>,
132    /// This record's identifier, minted by the store.
133    pub id: ActionId,
134    /// What the printer made of it, if it reached the printer.
135    #[serde(default, skip_serializing_if = "Option::is_none")]
136    pub outcome: Option<ExecutionOutcome>,
137    /// The print this request was made against.
138    pub print_id: PrintId,
139    /// The request itself.
140    pub request: ActionRequest,
141}
142
143/// Policy refused an action.
144#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
145pub struct ActionRejectedPayload {
146    /// The action's identifier.
147    pub action_id: ActionId,
148    /// The whole decision, carrying which rejection it was.
149    pub decision: PolicyDecision,
150}
151
152/// One request an actor made, at the instant it made it.
153#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
154pub struct ActionRequest {
155    /// What was asked for.
156    pub action: PrintAction,
157    /// Who asked.
158    pub actor: Actor,
159    /// When they asked.
160    pub requested_at: Timestamp,
161}
162
163/// An actor asked for an action.
164#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
165pub struct ActionRequestedPayload {
166    /// What was asked for.
167    pub action: PrintAction,
168    /// The action's identifier.
169    pub action_id: ActionId,
170    /// Who asked.
171    pub actor: Actor,
172}
173
174/// Who asked for something.
175#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
176pub enum Actor {
177    /// The supervising agent, naming its session.
178    #[serde(rename = "agent")]
179    Agent {
180        /// The supervision session the agent is acting in.
181        session_name: String,
182    },
183    /// A person.
184    #[serde(rename = "operator")]
185    Operator,
186    /// The supervisor itself.
187    #[serde(rename = "system")]
188    System,
189}
190
191/// An actor class, which is what a safety envelope grants actions to.
192#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
193pub enum ActorClass {
194    /// The supervising agent.
195    #[serde(rename = "agent")]
196    Agent,
197    /// A person.
198    #[serde(rename = "operator")]
199    Operator,
200    /// The supervisor itself.
201    #[serde(rename = "system")]
202    System,
203}
204
205/// One thing an adjustment may change.
206pub type Adjustable = String;
207
208/// The agent's written record of one supervision turn.
209///
210/// This is deliberately not how the agent acts: acting is a
211/// `PrintAction` that policy rules on.
212#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
213pub struct AgentAssessment {
214    /// How sure the agent is.
215    pub confidence: Confidence,
216    /// What the agent did.
217    pub did: String,
218    /// Whether the agent is escalating to a person.
219    pub escalating: bool,
220    /// Whether the print should carry on.
221    pub should_continue: bool,
222    /// One line saying what is happening.
223    pub summary: String,
224    /// Why it did it.
225    pub why: String,
226}
227
228/// The agent wrote down what it made of a turn.
229#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
230pub struct AgentAssessmentPayload {
231    /// What the agent answered with.
232    pub assessment: AgentAssessment,
233    /// The session the turn ran in.
234    pub session_name: String,
235}
236
237/// How sure the agent is.
238///
239/// A closed vocabulary rather than a number, because a number invites a
240/// precision the agent does not have.
241#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
242pub enum Confidence {
243    /// Not sure.
244    #[serde(rename = "low")]
245    Low,
246    /// Fairly sure.
247    #[serde(rename = "medium")]
248    Medium,
249    /// Sure.
250    #[serde(rename = "high")]
251    High,
252}
253
254/// What a context read answers.
255///
256/// The latest image is **materialized** here rather than left as the handle
257/// `PrintContext` carries: the one thing a supervision turn does with an
258/// image is look at it, and a handle is not something anything can open. The
259/// path is absolute on this server's own filesystem, exactly as
260/// `ImageAnswer`'s is, and is absent when there is no image or when the
261/// record is intact and the file is not.
262#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
263pub struct ContextAnswer {
264    /// Everything a supervision turn is given about the print.
265    pub context: PrintContext,
266    /// Where the latest image's bytes are, absolute on this host.
267    #[serde(default, skip_serializing_if = "Option::is_none")]
268    pub image_path: Option<String>,
269}
270
271/// The envelope intersected with the print's manifest.
272///
273/// This is what context reports, so that the agent can see its own limits
274/// before it asks. Computing one is the supervision core's; this crate
275/// declares
276/// the shape and nothing that produces it.
277#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
278pub struct EffectiveBounds {
279    /// The range each adjustable may be set to, inclusive.
280    pub allowed: BTreeMap<String, Range>,
281}
282
283/// What this server answers when it will not do what it was asked.
284#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
285pub struct ErrorAnswer {
286    /// One line saying why, in the words of whatever refused it.
287    pub error: String,
288}
289
290/// A lowercase hyphenated version 7 UUID identifying one event.
291pub type EventId = String;
292
293/// One event, as the store holds it.
294///
295/// `raw` holds the bytes exactly as received for an externally sourced event
296/// and is absent for an internally raised one — it is what makes the history
297/// auditable when a normalization turns out to be wrong. `print_id` is
298/// optional, because an externally sourced event may name no print this
299/// system
300/// knows.
301#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
302pub struct EventRecord {
303    /// This event's identifier, minted by the store.
304    pub id: EventId,
305    /// The image it arrived with, when it arrived with one.
306    #[serde(default, skip_serializing_if = "Option::is_none")]
307    pub image: Option<ImageRef>,
308    /// The print it belongs to, when it belongs to one.
309    #[serde(default, skip_serializing_if = "Option::is_none")]
310    pub print_id: Option<PrintId>,
311    /// The bytes exactly as received, for an externally sourced event.
312    #[serde(default, skip_serializing_if = "Option::is_none")]
313    pub raw: Option<RawBytes>,
314    /// When it was received.
315    pub received_at: Timestamp,
316    /// Where it came from.
317    pub source: EventSource,
318    /// Which arm this is, and what that arm carries. It travels flattened
319    /// into this object, under `kind`.
320    #[serde(flatten)]
321    pub kind: EventRecordKind,
322}
323
324/// Which arm one `EventRecord` is, and what that arm carries.
325#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
326#[serde(tag = "kind")]
327pub enum EventRecordKind {
328    /// Obico reported a print failure.
329    #[serde(rename = "obico_failure_alert")]
330    ObicoFailureAlert {
331        /// One shape of the contracts, which say nothing more about it.
332        payload: ObicoFailureAlertPayload,
333    },
334    /// Obico sent a printer notification.
335    #[serde(rename = "obico_printer_notification")]
336    ObicoPrinterNotification {
337        /// One shape of the contracts, which say nothing more about it.
338        payload: ObicoPrinterNotificationPayload,
339    },
340    /// An external body arrived that could not be read.
341    #[serde(rename = "malformed_external_event")]
342    MalformedExternalEvent {
343        /// One shape of the contracts, which say nothing more about it.
344        payload: MalformedExternalEventPayload,
345    },
346    /// An actor asked for an action.
347    #[serde(rename = "action_requested")]
348    ActionRequested {
349        /// One shape of the contracts, which say nothing more about it.
350        payload: ActionRequestedPayload,
351    },
352    /// An accepted action reached the printer.
353    #[serde(rename = "action_executed")]
354    ActionExecuted {
355        /// One shape of the contracts, which say nothing more about it.
356        payload: ActionExecutedPayload,
357    },
358    /// Policy refused an action.
359    #[serde(rename = "action_rejected")]
360    ActionRejected {
361        /// One shape of the contracts, which say nothing more about it.
362        payload: ActionRejectedPayload,
363    },
364    /// A bounded intervention expired.
365    #[serde(rename = "intervention_expired")]
366    InterventionExpired {
367        /// One shape of the contracts, which say nothing more about it.
368        payload: InterventionExpiredPayload,
369    },
370    /// A supervision session was opened.
371    #[serde(rename = "supervision_session_opened")]
372    SupervisionSessionOpened {
373        /// One shape of the contracts, which say nothing more about it.
374        payload: SupervisionSessionOpenedPayload,
375    },
376    /// A supervision session was closed.
377    #[serde(rename = "supervision_session_closed")]
378    SupervisionSessionClosed {
379        /// One shape of the contracts, which say nothing more about it.
380        payload: SupervisionSessionClosedPayload,
381    },
382    /// The agent wrote down what it made of a turn.
383    #[serde(rename = "agent_assessment")]
384    AgentAssessment {
385        /// One shape of the contracts, which say nothing more about it.
386        payload: AgentAssessmentPayload,
387    },
388    /// An operator acknowledged an event.
389    #[serde(rename = "operator_acknowledgement")]
390    OperatorAcknowledgement {
391        /// One shape of the contracts, which say nothing more about it.
392        payload: OperatorAcknowledgementPayload,
393    },
394    /// A port failed while an event was being handled.
395    #[serde(rename = "port_failure")]
396    PortFailure {
397        /// One shape of the contracts, which say nothing more about it.
398        payload: PortFailurePayload,
399    },
400    /// A supervisor reconciled one thing the store held when it started.
401    #[serde(rename = "startup_reconciliation")]
402    StartupReconciliation {
403        /// One shape of the contracts, which say nothing more about it.
404        payload: StartupReconciliationPayload,
405    },
406}
407
408/// Where an event came from.
409#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
410pub enum EventSource {
411    /// Obico, over its webhook.
412    #[serde(rename = "obico")]
413    Obico,
414    /// A person.
415    #[serde(rename = "operator")]
416    Operator,
417    /// The supervising agent.
418    #[serde(rename = "agent")]
419    Agent,
420    /// The supervisor itself.
421    #[serde(rename = "system")]
422    System,
423}
424
425/// What happened when an accepted action reached the printer.
426#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
427pub enum ExecutionOutcome {
428    /// The printer took it.
429    #[serde(rename = "succeeded")]
430    Succeeded,
431    /// The printer did not, for this reason.
432    #[serde(rename = "failed")]
433    Failed {
434        /// Why it failed.
435        reason: String,
436    },
437}
438
439/// A file name a printer's own file API can be asked for: no path separator,
440/// no NUL byte, no `.` or `..` segment, no drive prefix, and not empty.
441pub type FileName = String;
442
443/// One heater, as a source reported it.
444///
445/// Every field is optional, because a source that reports no heater at all
446/// reports none of these; each is a plausibility-ranged reported value in
447/// degrees Celsius.
448#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
449pub struct HeaterSnapshot {
450    /// The temperature the heater is at.
451    #[serde(default, skip_serializing_if = "Option::is_none")]
452    pub actual_c: Option<Reported>,
453    /// The offset applied to this heater's target.
454    #[serde(default, skip_serializing_if = "Option::is_none")]
455    pub offset_c: Option<Reported>,
456    /// The temperature the heater is driving towards.
457    #[serde(default, skip_serializing_if = "Option::is_none")]
458    pub target_c: Option<Reported>,
459}
460
461/// What a history read answers.
462#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
463pub struct HistoryAnswer {
464    /// The print's events, newest first.
465    pub events: Vec<EventRecord>,
466}
467
468/// What an image read answers.
469///
470/// The path is absolute on this server's own filesystem, and is the whole of
471/// the answer about the bytes: nothing here renders them, encodes them or
472/// serves them. It is absent when the record is intact and the file is not,
473/// which is a different answer from there being no such image.
474#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
475pub struct ImageAnswer {
476    /// Where its bytes are, absolute on this host.
477    #[serde(default, skip_serializing_if = "Option::is_none")]
478    pub path: Option<String>,
479    /// The record.
480    pub record: ImageRecord,
481}
482
483/// A lowercase hyphenated version 7 UUID identifying one image.
484pub type ImageId = String;
485
486/// One image, stored beside the event it arrived with.
487///
488/// `relative_path` is relative to the configured state directory, so that the
489/// store stays portable. Materializing an image resolves that to an absolute
490/// path; nothing in this system renders image bytes into JSON.
491#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
492pub struct ImageRecord {
493    /// How many bytes it is.
494    pub byte_len: i64,
495    /// The content type it was served as.
496    pub content_type: String,
497    /// The event it arrived with.
498    pub event_id: EventId,
499    /// When it was fetched.
500    pub fetched_at: Timestamp,
501    /// This image's identifier, minted by the store.
502    pub id: ImageId,
503    /// The print it belongs to.
504    pub print_id: PrintId,
505    /// Where it lives, relative to the configured state directory.
506    pub relative_path: String,
507    /// The SHA-256 of its bytes, lowercase hexadecimal.
508    pub sha256: String,
509    /// Where it was fetched from, when it was fetched from somewhere.
510    #[serde(default, skip_serializing_if = "Option::is_none")]
511    pub source_url: Option<String>,
512}
513
514/// The handle an image travels in context under.
515#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
516pub struct ImageRef {
517    /// The image's identifier.
518    pub id: ImageId,
519    /// The SHA-256 of its bytes, lowercase hexadecimal.
520    pub sha256: String,
521}
522
523/// One adjustment made for a bounded time.
524///
525/// `prior_value` is read from the printer snapshot taken before the change,
526/// and
527/// is absent when the printer reported none — in which case expiry restores
528/// nothing and the outcome says so rather than guessing a default.
529#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
530pub struct Intervention {
531    /// The action that asked for it.
532    pub action_id: ActionId,
533    /// What it changed.
534    pub adjustable: Adjustable,
535    /// When it was applied.
536    pub applied_at: Timestamp,
537    /// What it was changed to.
538    pub applied_value: f64,
539    /// When it stops standing.
540    pub expires_at: Timestamp,
541    /// This intervention's identifier, minted by the store.
542    pub id: InterventionId,
543    /// What became of it.
544    pub outcome: InterventionOutcome,
545    /// The print it was made against.
546    pub print_id: PrintId,
547    /// What the printer reported before the change, if it reported anything.
548    #[serde(default, skip_serializing_if = "Option::is_none")]
549    pub prior_value: Option<f64>,
550    /// When the prior value was put back, if it was.
551    #[serde(default, skip_serializing_if = "Option::is_none")]
552    pub restored_at: Option<Timestamp>,
553}
554
555/// A bounded intervention expired.
556#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
557pub struct InterventionExpiredPayload {
558    /// What it had changed.
559    pub adjustable: Adjustable,
560    /// The intervention's identifier.
561    pub intervention_id: InterventionId,
562    /// What became of it.
563    pub outcome: InterventionOutcome,
564}
565
566/// A lowercase hyphenated version 7 UUID identifying one bounded
567/// intervention.
568pub type InterventionId = String;
569
570/// What became of a bounded change.
571#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
572pub enum InterventionOutcome {
573    /// It is still in force.
574    #[serde(rename = "still_active")]
575    StillActive,
576    /// The prior value was put back.
577    #[serde(rename = "restored")]
578    Restored,
579    /// There was no prior value to put back.
580    #[serde(rename = "restore_unavailable")]
581    RestoreUnavailable,
582    /// Putting the prior value back failed.
583    #[serde(rename = "restore_failed")]
584    RestoreFailed {
585        /// Why it failed.
586        reason: String,
587    },
588    /// Another intervention replaced it before it expired.
589    #[serde(rename = "superseded")]
590    Superseded {
591        /// The intervention that replaced it.
592        by: InterventionId,
593    },
594}
595
596/// What a sliced job declares about itself and about what may be adjusted.
597///
598/// An adjustable the manifest does not name takes the envelope's own range; a
599/// manifest range wider than the envelope's is narrowed to the envelope's and
600/// the narrowing is recorded on the print. A manifest may only narrow.
601#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
602pub struct JobManifest {
603    /// The range each named adjustable may take, inclusive.
604    pub allowed: BTreeMap<String, Range>,
605    /// The file this manifest is about, as the slicer named it.
606    pub file_name: String,
607    /// The material the job is sliced for.
608    pub material: String,
609    /// Whatever else the slicer recorded.
610    pub metadata: BTreeMap<String, String>,
611    /// The nozzle the job is sliced for, in millimetres.
612    pub nozzle_diameter_mm: f64,
613    /// The slicer profile the job was sliced with.
614    pub slicer_profile: String,
615}
616
617/// The job a printer reports it is running.
618///
619/// Every field but `state` is optional: an absent one means the source did
620/// not
621/// report it.
622#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
623pub struct JobSnapshot {
624    /// How far through the print is, as a fraction from zero to one.
625    ///
626    /// Normalized to a fraction here regardless of how the source expresses
627    /// it.
628    #[serde(default, skip_serializing_if = "Option::is_none")]
629    pub completion: Option<Reported>,
630    /// The error the source reports, when it reports one.
631    #[serde(default, skip_serializing_if = "Option::is_none")]
632    pub error: Option<String>,
633    /// The whole print's estimated duration, in whole seconds.
634    #[serde(default, skip_serializing_if = "Option::is_none")]
635    pub estimated_print_time_s: Option<i64>,
636    /// The name of the file being printed, as the source reported it.
637    #[serde(default, skip_serializing_if = "Option::is_none")]
638    pub file_name: Option<String>,
639    /// Where the file lives, in the source's own vocabulary.
640    #[serde(default, skip_serializing_if = "Option::is_none")]
641    pub file_origin: Option<String>,
642    /// How long the print has left, in whole seconds.
643    #[serde(default, skip_serializing_if = "Option::is_none")]
644    pub print_time_left_s: Option<i64>,
645    /// How long the print has been running, in whole seconds.
646    #[serde(default, skip_serializing_if = "Option::is_none")]
647    pub print_time_s: Option<i64>,
648    /// The file's size in bytes.
649    #[serde(default, skip_serializing_if = "Option::is_none")]
650    pub size_bytes: Option<i64>,
651    /// The state the source reports the job to be in.
652    pub state: PrinterState,
653}
654
655/// An external body arrived that could not be read.
656///
657/// This kind always carries its `raw` bytes, and it exists so that an alert
658/// this system cannot read is written down rather than dropped.
659#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
660pub struct MalformedExternalEventPayload {
661    /// One line saying why the body could not be read.
662    pub detail: String,
663}
664
665/// What a manifest read or write answers.
666#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
667pub struct ManifestAnswer {
668    /// The manifest, when the print has one.
669    #[serde(default, skip_serializing_if = "Option::is_none")]
670    pub manifest: Option<JobManifest>,
671    /// Every range this manifest asked wider than the envelope allows,
672    /// narrowed
673    /// to the envelope's — recorded on the print, so nobody has to wonder
674    /// later
675    /// which bound applied.
676    pub narrowings: Vec<ManifestNarrowing>,
677}
678
679/// One adjustable whose manifest range was wider than the envelope's.
680#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
681pub struct ManifestNarrowing {
682    /// The adjustable that was narrowed.
683    pub adjustable: Adjustable,
684    /// The range that stands.
685    pub applied: Range,
686    /// The range the manifest asked for.
687    pub requested: Range,
688}
689
690/// Obico reported a print failure.
691///
692/// The two instants are optional because Obico's own field for each is a Unix
693/// timestamp number, an empty string, or absent, and the last two both mean
694/// the
695/// producer reported no instant. An absent field here is that, never an epoch
696/// date standing in for it.
697#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
698pub struct ObicoFailureAlertPayload {
699    /// When the print ended, when Obico reported an instant for it.
700    #[serde(default, skip_serializing_if = "Option::is_none")]
701    pub ended_at: Option<Timestamp>,
702    /// The file being printed, when Obico named one.
703    #[serde(default, skip_serializing_if = "Option::is_none")]
704    pub file_name: Option<String>,
705    /// Whether Obico called it a warning rather than a failure.
706    pub is_warning: bool,
707    /// Obico's own identifier for the print, when it named one.
708    #[serde(default, skip_serializing_if = "Option::is_none")]
709    pub obico_print_id: Option<i64>,
710    /// Whether Obico paused the print itself.
711    pub print_paused: bool,
712    /// When the print started, when Obico reported an instant for it.
713    #[serde(default, skip_serializing_if = "Option::is_none")]
714    pub started_at: Option<Timestamp>,
715}
716
717/// The kind of printer notification Obico sent, normalized.
718#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
719pub enum ObicoNotificationType {
720    /// A print started.
721    #[serde(rename = "started")]
722    Started,
723    /// A print finished.
724    #[serde(rename = "done")]
725    Done,
726    /// A print was cancelled.
727    #[serde(rename = "cancelled")]
728    Cancelled,
729    /// A print was paused.
730    #[serde(rename = "paused")]
731    Paused,
732    /// A print was resumed.
733    #[serde(rename = "resumed")]
734    Resumed,
735    /// The printer is waiting for a filament change.
736    #[serde(rename = "filament_change")]
737    FilamentChange,
738    /// A heater cooled down.
739    #[serde(rename = "heater_cooled")]
740    HeaterCooled,
741    /// A heater reached its target.
742    #[serde(rename = "heater_target")]
743    HeaterTarget,
744}
745
746/// Obico sent a printer notification.
747///
748/// The two instants are optional for the same reason
749/// `ObicoFailureAlertPayload`'s are, and are absent along with the rest of
750/// the print's fields when the notification is about no print at all.
751#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
752pub struct ObicoPrinterNotificationPayload {
753    /// When the print ended, when Obico reported an instant for it.
754    #[serde(default, skip_serializing_if = "Option::is_none")]
755    pub ended_at: Option<Timestamp>,
756    /// The file being printed, when the notification is about one.
757    #[serde(default, skip_serializing_if = "Option::is_none")]
758    pub file_name: Option<String>,
759    /// Which notification it is.
760    pub notification_type: ObicoNotificationType,
761    /// Obico's own identifier for the print, when the notification is about
762    /// one.
763    #[serde(default, skip_serializing_if = "Option::is_none")]
764    pub obico_print_id: Option<i64>,
765    /// When the print started, when Obico reported an instant for it.
766    #[serde(default, skip_serializing_if = "Option::is_none")]
767    pub started_at: Option<Timestamp>,
768}
769
770/// An operator acknowledged an event.
771#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
772pub struct OperatorAcknowledgementPayload {
773    /// The event being acknowledged.
774    pub acknowledged_event_id: EventId,
775    /// What the operator asked for next.
776    pub disposition: AcknowledgementDisposition,
777}
778
779/// The decision policy took on one request.
780#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
781pub enum PolicyDecision {
782    /// The request may proceed.
783    #[serde(rename = "accepted")]
784    Accepted,
785    /// The request may not, for this reason.
786    #[serde(rename = "rejected")]
787    Rejected(RejectionReason),
788}
789
790/// A port failed while one event was being handled.
791///
792/// The event is named rather than implied, so that a reader holding an
793/// event's
794/// identifier reaches every failure recorded while that event was being
795/// handled. A failure recorded here is one the handling survived: the event
796/// is
797/// already in the history by the time any of these sites is reached, and the
798/// loop goes on to handle the next event.
799#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
800pub struct PortFailurePayload {
801    /// What the port said about it, in the port's own words.
802    pub detail: String,
803    /// The event whose handling reached the failing call.
804    pub event_id: EventId,
805    /// Where it failed.
806    pub site: PortFailureSite,
807}
808
809/// Where a port failed while an event was being handled.
810///
811/// A closed set of exactly the sites at which a failure has nowhere else to
812/// be
813/// recorded. The printer's action methods record theirs on the
814/// `ActionRecord` the request minted, and a restoring
815/// call records its own on the `Intervention` it was
816/// expiring; those are not sites here, because a second record of them would
817/// be
818/// a second version of one fact.
819#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
820pub enum PortFailureSite {
821    /// Reading the printer's own state.
822    #[serde(rename = "printer_snapshot")]
823    PrinterSnapshot,
824    /// Reading the job the printer reports it is running.
825    #[serde(rename = "printer_job")]
826    PrinterJob,
827    /// Writing the image the event arrived with.
828    #[serde(rename = "image_write")]
829    ImageWrite,
830    /// Running the supervision turn the event prompted.
831    #[serde(rename = "supervision_turn")]
832    SupervisionTurn,
833}
834
835/// The whole vocabulary an actor may ask for, and there is no other.
836#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
837#[serde(tag = "action")]
838pub enum PrintAction {
839    /// Pause the print.
840    #[serde(rename = "pause")]
841    Pause {
842        /// Who is asking.
843        actor: Actor,
844        /// Why the actor is asking for this.
845        reason: String,
846    },
847    /// Resume the print.
848    #[serde(rename = "resume")]
849    Resume {
850        /// Who is asking.
851        actor: Actor,
852        /// Why the actor is asking for this.
853        reason: String,
854    },
855    /// Cancel the print.
856    #[serde(rename = "cancel")]
857    Cancel {
858        /// Who is asking.
859        actor: Actor,
860        /// Why the actor is asking for this.
861        reason: String,
862    },
863    /// Start a print of a named file, with a manifest.
864    #[serde(rename = "start_print")]
865    StartPrint {
866        /// Who is asking.
867        actor: Actor,
868        /// The file to print, validated as a name a file API can be asked
869        /// for.
870        file_name: FileName,
871        /// The manifest this print is bounded by.
872        manifest: JobManifest,
873        /// Why the actor is asking for this.
874        reason: String,
875    },
876    /// Set the feedrate factor, where one means one hundred percent.
877    #[serde(rename = "set_feedrate_factor")]
878    SetFeedrateFactor {
879        /// Who is asking.
880        actor: Actor,
881        /// How long the change stands for, in whole seconds.
882        #[serde(default, skip_serializing_if = "Option::is_none")]
883        duration_s: Option<i64>,
884        /// The multiplier asked for.
885        factor: f64,
886        /// Why the actor is asking for this.
887        reason: String,
888    },
889    /// Set the flowrate factor, where one means one hundred percent.
890    #[serde(rename = "set_flowrate_factor")]
891    SetFlowrateFactor {
892        /// Who is asking.
893        actor: Actor,
894        /// How long the change stands for, in whole seconds.
895        #[serde(default, skip_serializing_if = "Option::is_none")]
896        duration_s: Option<i64>,
897        /// The multiplier asked for.
898        factor: f64,
899        /// Why the actor is asking for this.
900        reason: String,
901    },
902    /// Set one tool's target temperature.
903    #[serde(rename = "set_tool_target_c")]
904    SetToolTargetC {
905        /// Who is asking.
906        actor: Actor,
907        /// How long the change stands for, in whole seconds.
908        #[serde(default, skip_serializing_if = "Option::is_none")]
909        duration_s: Option<i64>,
910        /// Why the actor is asking for this.
911        reason: String,
912        /// The target temperature asked for, in degrees Celsius.
913        target_c: f64,
914        /// The tool, in the printer's own numbering.
915        tool: i64,
916    },
917    /// Set the bed's target temperature.
918    #[serde(rename = "set_bed_target_c")]
919    SetBedTargetC {
920        /// Who is asking.
921        actor: Actor,
922        /// How long the change stands for, in whole seconds.
923        #[serde(default, skip_serializing_if = "Option::is_none")]
924        duration_s: Option<i64>,
925        /// Why the actor is asking for this.
926        reason: String,
927        /// The target temperature asked for, in degrees Celsius.
928        target_c: f64,
929    },
930    /// Set the part-cooling fan percentage.
931    #[serde(rename = "set_fan_percent")]
932    SetFanPercent {
933        /// Who is asking.
934        actor: Actor,
935        /// How long the change stands for, in whole seconds.
936        #[serde(default, skip_serializing_if = "Option::is_none")]
937        duration_s: Option<i64>,
938        /// The percentage asked for.
939        percent: f64,
940        /// Why the actor is asking for this.
941        reason: String,
942    },
943    /// Acknowledge a failure event, with a disposition.
944    #[serde(rename = "acknowledge_failure")]
945    AcknowledgeFailure {
946        /// Who is asking.
947        actor: Actor,
948        /// What to do next.
949        disposition: AcknowledgementDisposition,
950        /// The event being acknowledged.
951        event_id: EventId,
952        /// Why the actor is asking for this.
953        reason: String,
954    },
955}
956
957/// Everything a supervision turn is given about one print.
958#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
959pub struct PrintContext {
960    /// The limits in force, so that the agent can see them before it asks.
961    pub bounds: EffectiveBounds,
962    /// The interventions still active.
963    pub interventions: Vec<Intervention>,
964    /// The job, when a snapshot could be taken.
965    #[serde(default, skip_serializing_if = "Option::is_none")]
966    pub job: Option<JobSnapshot>,
967    /// The most recent image, when there is one.
968    #[serde(default, skip_serializing_if = "Option::is_none")]
969    pub latest_image: Option<ImageRef>,
970    /// The manifest, when the print has one.
971    #[serde(default, skip_serializing_if = "Option::is_none")]
972    pub manifest: Option<JobManifest>,
973    /// The print itself.
974    pub print: PrintRecord,
975    /// The printer, when a snapshot could be taken.
976    #[serde(default, skip_serializing_if = "Option::is_none")]
977    pub printer: Option<PrinterSnapshot>,
978    /// A bounded list of this print's events, newest first.
979    pub recent_events: Vec<EventRecord>,
980}
981
982/// A lowercase hyphenated version 7 UUID identifying one print.
983pub type PrintId = String;
984
985/// One print, and the record supervision keys from.
986///
987/// Obico's own print id is carried beside this record's identifier rather
988/// than
989/// as it, because a print may be observed before Obico has one.
990#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
991pub struct PrintRecord {
992    /// Why it ended, if it has.
993    #[serde(default, skip_serializing_if = "Option::is_none")]
994    pub end_reason: Option<String>,
995    /// When it ended, if it has.
996    #[serde(default, skip_serializing_if = "Option::is_none")]
997    pub ended_at: Option<Timestamp>,
998    /// The file being printed, as the source reported it.
999    #[serde(default, skip_serializing_if = "Option::is_none")]
1000    pub file_name: Option<String>,
1001    /// This print's identifier, minted by the store.
1002    pub id: PrintId,
1003    /// Every manifest range this print narrowed to the envelope's.
1004    pub narrowings: Vec<ManifestNarrowing>,
1005    /// Obico's own identifier for the print, when Obico has one.
1006    #[serde(default, skip_serializing_if = "Option::is_none")]
1007    pub obico_print_id: Option<i64>,
1008    /// When the print was opened.
1009    pub opened_at: Timestamp,
1010    /// The state the print is in.
1011    pub state: PrinterState,
1012}
1013
1014/// A printer, as a source reported it at one instant.
1015#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1016pub struct PrinterSnapshot {
1017    /// The bed heater, when the printer reports one.
1018    #[serde(default, skip_serializing_if = "Option::is_none")]
1019    pub bed: Option<HeaterSnapshot>,
1020    /// The chamber heater, when the printer reports one.
1021    #[serde(default, skip_serializing_if = "Option::is_none")]
1022    pub chamber: Option<HeaterSnapshot>,
1023    /// The state the printer is in.
1024    pub connection: PrinterState,
1025    /// The part-cooling fan, in percent.
1026    #[serde(default, skip_serializing_if = "Option::is_none")]
1027    pub fan_percent: Option<Reported>,
1028    /// The feedrate multiplier, where one means one hundred percent.
1029    #[serde(default, skip_serializing_if = "Option::is_none")]
1030    pub feedrate_factor: Option<Reported>,
1031    /// The flowrate multiplier, where one means one hundred percent.
1032    #[serde(default, skip_serializing_if = "Option::is_none")]
1033    pub flowrate_factor: Option<Reported>,
1034    /// The instant this observation was taken.
1035    pub observed_at: Timestamp,
1036    /// The tool heaters, indexed by tool number.
1037    pub tools: Vec<HeaterSnapshot>,
1038}
1039
1040/// The state a source reports a printer or a print to be in.
1041///
1042/// The `unknown` arm exists so that a state nobody anticipated is recorded
1043/// carrying the source's own word for it rather than lost.
1044#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1045pub enum PrinterState {
1046    /// Connected and idle.
1047    #[serde(rename = "operational")]
1048    Operational,
1049    /// Printing, but paused.
1050    #[serde(rename = "paused")]
1051    Paused,
1052    /// Printing.
1053    #[serde(rename = "printing")]
1054    Printing,
1055    /// Cancelling a print.
1056    #[serde(rename = "cancelling")]
1057    Cancelling,
1058    /// In an error state.
1059    #[serde(rename = "error")]
1060    Error,
1061    /// Not reachable.
1062    #[serde(rename = "offline")]
1063    Offline,
1064    /// A state this vocabulary does not name, in the source's own word for
1065    /// it.
1066    #[serde(rename = "unknown")]
1067    Unknown(String),
1068}
1069
1070/// An inclusive pair of 64-bit floats.
1071#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1072pub struct Range {
1073    /// The highest value the range admits, inclusive.
1074    pub max: f64,
1075    /// The lowest value the range admits, inclusive.
1076    pub min: f64,
1077}
1078
1079/// Bytes exactly as received, base64-encoded.
1080pub type RawBytes = String;
1081
1082/// Why a request was refused.
1083///
1084/// Each rejection is a distinct variant, so a consumer distinguishes them by
1085/// matching rather than by reading a message.
1086#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1087pub enum RejectionReason {
1088    /// The value asked for is outside the range allowed for that adjustable.
1089    #[serde(rename = "out_of_bounds")]
1090    OutOfBounds {
1091        /// The adjustable that was asked for.
1092        adjustable: Adjustable,
1093        /// The range that was allowed.
1094        allowed: Range,
1095        /// The value that was asked for.
1096        requested: f64,
1097    },
1098    /// This actor class may not request this action at all.
1099    #[serde(rename = "actor_may_not_request")]
1100    ActorMayNotRequest {
1101        /// The action they asked for.
1102        action: ActionKind,
1103        /// The class of the actor that asked.
1104        actor_class: ActorClass,
1105    },
1106    /// There is no active print to act on.
1107    #[serde(rename = "no_active_print")]
1108    NoActivePrint,
1109    /// The printer is not in a state this action is valid from.
1110    #[serde(rename = "invalid_from_state")]
1111    InvalidFromState {
1112        /// The state the printer is in.
1113        state: PrinterState,
1114    },
1115    /// The agent's minimum interval has not elapsed.
1116    #[serde(rename = "min_interval_not_elapsed")]
1117    MinIntervalNotElapsed {
1118        /// The minimum interval, in whole seconds.
1119        interval_s: i64,
1120        /// How long it has been since the last agent action, in whole
1121        /// seconds.
1122        since_last_s: i64,
1123    },
1124    /// The adjustable is not one this printer has.
1125    #[serde(rename = "unsupported_adjustable")]
1126    UnsupportedAdjustable {
1127        /// The adjustable this printer cannot express.
1128        adjustable: Adjustable,
1129    },
1130}
1131
1132/// A value as a source reported it, flagged when it is outside the
1133/// plausibility range this crate declares for its field.
1134#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1135pub struct Reported {
1136    /// One shape of the contracts, which say nothing more about it.
1137    pub out_of_range: bool,
1138    /// One shape of the contracts, which say nothing more about it.
1139    pub value: f64,
1140}
1141
1142/// What one restart put back the way it found it.
1143///
1144/// A supervisor that has been restarted adopts whatever the store holds
1145/// rather
1146/// than starting empty, and each of these is one of those adoptions. They are
1147/// recorded rather than merely done, because a print that carried on across a
1148/// restart and one that was started again look identical afterwards unless
1149/// the
1150/// history says which happened.
1151#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1152pub enum StartupOutcome {
1153    /// A print left open was adopted as the print this supervisor is
1154    /// watching.
1155    #[serde(rename = "print_adopted")]
1156    PrintAdopted,
1157    /// A session left open was resumed rather than replaced.
1158    #[serde(rename = "session_resumed")]
1159    SessionResumed {
1160        /// The session's own name in the harness.
1161        session_name: String,
1162    },
1163    /// An intervention already past its expiry was expired on start.
1164    #[serde(rename = "intervention_expired")]
1165    InterventionExpired {
1166        /// What it had changed.
1167        adjustable: Adjustable,
1168        /// The intervention that had outlived its bound.
1169        intervention_id: InterventionId,
1170        /// What became of putting the prior value back.
1171        outcome: InterventionOutcome,
1172    },
1173}
1174
1175/// A supervisor reconciled one thing the store held when it started.
1176#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1177pub struct StartupReconciliationPayload {
1178    /// What was reconciled.
1179    pub outcome: StartupOutcome,
1180    /// The print it is about.
1181    pub print_id: PrintId,
1182}
1183
1184/// What a status read answers.
1185#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1186pub struct StatusAnswer {
1187    /// The bounded interventions still in force.
1188    pub interventions: Vec<Intervention>,
1189    /// The job, when a snapshot could be taken.
1190    #[serde(default, skip_serializing_if = "Option::is_none")]
1191    pub job: Option<JobSnapshot>,
1192    /// The print.
1193    pub print: PrintRecord,
1194    /// The printer, when a snapshot could be taken.
1195    #[serde(default, skip_serializing_if = "Option::is_none")]
1196    pub printer: Option<PrinterSnapshot>,
1197    /// The supervision session watching it, when one is.
1198    #[serde(default, skip_serializing_if = "Option::is_none")]
1199    pub session: Option<SupervisionSession>,
1200}
1201
1202/// The supervision session keyed to one print.
1203#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1204pub struct SupervisionSession {
1205    /// Why it was closed, if it was.
1206    #[serde(default, skip_serializing_if = "Option::is_none")]
1207    pub close_reason: Option<String>,
1208    /// When the session was closed, if it was.
1209    #[serde(default, skip_serializing_if = "Option::is_none")]
1210    pub closed_at: Option<Timestamp>,
1211    /// When the session was opened.
1212    pub created_at: Timestamp,
1213    /// The identity the harness ran the session under.
1214    pub harness_identity: String,
1215    /// When the last turn ran.
1216    pub last_turn_at: Timestamp,
1217    /// The print this session watches.
1218    pub print_id: PrintId,
1219    /// The session's own name in the harness.
1220    pub session_name: String,
1221}
1222
1223/// A supervision session was closed.
1224#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1225pub struct SupervisionSessionClosedPayload {
1226    /// Why it was closed.
1227    pub close_reason: String,
1228    /// The session's own name in the harness.
1229    pub session_name: String,
1230}
1231
1232/// A supervision session was opened.
1233#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1234pub struct SupervisionSessionOpenedPayload {
1235    /// The identity the harness ran it under.
1236    pub harness_identity: String,
1237    /// The session's own name in the harness.
1238    pub session_name: String,
1239}
1240
1241/// An instant in UTC, as an RFC 3339 string with a zero offset.
1242pub type Timestamp = String;
1243
1244impl Client {
1245    /// Call `status` on the configured supervisor.
1246    ///
1247    /// # Errors
1248    ///
1249    /// Returns `ClientError` when the supervisor could not be reached, when
1250    /// it answered something this client cannot read.
1251    pub fn status(&self, print_id: &str) -> Result<StatusAnswer, ClientError> {
1252        let target = format!("/v1/prints/{print_id}/status");
1253        let asked: Vec<(String, String)> = Vec::new();
1254        let sending: Option<serde_json::Value> = None;
1255        self.call("GET", &target, &asked, sending.as_ref())
1256    }
1257
1258    /// Call `context` on the configured supervisor.
1259    ///
1260    /// # Errors
1261    ///
1262    /// Returns `ClientError` when the supervisor could not be reached, when
1263    /// it answered something this client cannot read.
1264    pub fn context(&self, print_id: &str) -> Result<ContextAnswer, ClientError> {
1265        let target = format!("/v1/prints/{print_id}/context");
1266        let asked: Vec<(String, String)> = Vec::new();
1267        let sending: Option<serde_json::Value> = None;
1268        self.call("GET", &target, &asked, sending.as_ref())
1269    }
1270
1271    /// Call `image` on the configured supervisor.
1272    ///
1273    /// # Errors
1274    ///
1275    /// Returns `ClientError` when the supervisor could not be reached, when
1276    /// it answered something this client cannot read.
1277    pub fn image(&self, image_id: &str) -> Result<ImageAnswer, ClientError> {
1278        let target = format!("/v1/images/{image_id}");
1279        let asked: Vec<(String, String)> = Vec::new();
1280        let sending: Option<serde_json::Value> = None;
1281        self.call("GET", &target, &asked, sending.as_ref())
1282    }
1283
1284    /// Call `history` on the configured supervisor.
1285    ///
1286    /// # Errors
1287    ///
1288    /// Returns `ClientError` when the supervisor could not be reached, when
1289    /// it answered something this client cannot read.
1290    pub fn history(
1291        &self,
1292        print_id: &str,
1293        limit: Option<i64>,
1294    ) -> Result<HistoryAnswer, ClientError> {
1295        let target = format!("/v1/prints/{print_id}/history");
1296        let mut asked: Vec<(String, String)> = Vec::new();
1297        if let Some(value) = limit {
1298            asked.push(("limit".to_owned(), value.to_string()));
1299        }
1300        let sending: Option<serde_json::Value> = None;
1301        self.call("GET", &target, &asked, sending.as_ref())
1302    }
1303
1304    /// Call `manifest_get` on the configured supervisor.
1305    ///
1306    /// # Errors
1307    ///
1308    /// Returns `ClientError` when the supervisor could not be reached, when
1309    /// it answered something this client cannot read.
1310    pub fn manifest_get(&self, print_id: &str) -> Result<ManifestAnswer, ClientError> {
1311        let target = format!("/v1/prints/{print_id}/manifest");
1312        let asked: Vec<(String, String)> = Vec::new();
1313        let sending: Option<serde_json::Value> = None;
1314        self.call("GET", &target, &asked, sending.as_ref())
1315    }
1316
1317    /// Call `manifest_set` on the configured supervisor.
1318    ///
1319    /// # Errors
1320    ///
1321    /// Returns `ClientError` when the supervisor could not be reached, when
1322    /// it answered something this client cannot read, when this client
1323    /// refuses the call before making it because the reason is empty, and
1324    /// when the policy refused the action — which arrives as
1325    /// `ClientError::Rejected`, carrying the reason, the value asked for and
1326    /// the range allowed.
1327    pub fn manifest_set(
1328        &self,
1329        print_id: &str,
1330        reason: &str,
1331        manifest: &JobManifest,
1332    ) -> Result<ManifestAnswer, ClientError> {
1333        crate::reason_given(reason)?;
1334        let target = format!("/v1/prints/{print_id}/manifest");
1335        let asked: Vec<(String, String)> = Vec::new();
1336        let mut sending = serde_json::Map::new();
1337        sending.insert("reason".to_owned(), crate::as_value(&reason)?);
1338        sending.insert("manifest".to_owned(), crate::as_value(&manifest)?);
1339        let sending = Some(serde_json::Value::Object(sending));
1340        self.call("PUT", &target, &asked, sending.as_ref())
1341    }
1342
1343    /// Call `pause` on the configured supervisor.
1344    ///
1345    /// # Errors
1346    ///
1347    /// Returns `ClientError` when the supervisor could not be reached, when
1348    /// it answered something this client cannot read, when this client
1349    /// refuses the call before making it because the reason is empty, and
1350    /// when the policy refused the action — which arrives as
1351    /// `ClientError::Rejected`, carrying the reason, the value asked for and
1352    /// the range allowed.
1353    pub fn pause(&self, print_id: &str, reason: &str) -> Result<ActionAnswer, ClientError> {
1354        crate::reason_given(reason)?;
1355        let target = format!("/v1/prints/{print_id}/actions/pause");
1356        let asked: Vec<(String, String)> = Vec::new();
1357        let mut sending = serde_json::Map::new();
1358        sending.insert("actor".to_owned(), crate::as_value(&self.actor())?);
1359        sending.insert("reason".to_owned(), crate::as_value(&reason)?);
1360        let sending = Some(serde_json::Value::Object(sending));
1361        self.call("POST", &target, &asked, sending.as_ref())
1362    }
1363
1364    /// Call `resume` on the configured supervisor.
1365    ///
1366    /// # Errors
1367    ///
1368    /// Returns `ClientError` when the supervisor could not be reached, when
1369    /// it answered something this client cannot read, when this client
1370    /// refuses the call before making it because the reason is empty, and
1371    /// when the policy refused the action — which arrives as
1372    /// `ClientError::Rejected`, carrying the reason, the value asked for and
1373    /// the range allowed.
1374    pub fn resume(&self, print_id: &str, reason: &str) -> Result<ActionAnswer, ClientError> {
1375        crate::reason_given(reason)?;
1376        let target = format!("/v1/prints/{print_id}/actions/resume");
1377        let asked: Vec<(String, String)> = Vec::new();
1378        let mut sending = serde_json::Map::new();
1379        sending.insert("actor".to_owned(), crate::as_value(&self.actor())?);
1380        sending.insert("reason".to_owned(), crate::as_value(&reason)?);
1381        let sending = Some(serde_json::Value::Object(sending));
1382        self.call("POST", &target, &asked, sending.as_ref())
1383    }
1384
1385    /// Call `cancel` on the configured supervisor.
1386    ///
1387    /// # Errors
1388    ///
1389    /// Returns `ClientError` when the supervisor could not be reached, when
1390    /// it answered something this client cannot read, when this client
1391    /// refuses the call before making it because the reason is empty, and
1392    /// when the policy refused the action — which arrives as
1393    /// `ClientError::Rejected`, carrying the reason, the value asked for and
1394    /// the range allowed.
1395    pub fn cancel(&self, print_id: &str, reason: &str) -> Result<ActionAnswer, ClientError> {
1396        crate::reason_given(reason)?;
1397        let target = format!("/v1/prints/{print_id}/actions/cancel");
1398        let asked: Vec<(String, String)> = Vec::new();
1399        let mut sending = serde_json::Map::new();
1400        sending.insert("actor".to_owned(), crate::as_value(&self.actor())?);
1401        sending.insert("reason".to_owned(), crate::as_value(&reason)?);
1402        let sending = Some(serde_json::Value::Object(sending));
1403        self.call("POST", &target, &asked, sending.as_ref())
1404    }
1405
1406    /// Call `start_print` on the configured supervisor.
1407    ///
1408    /// # Errors
1409    ///
1410    /// Returns `ClientError` when the supervisor could not be reached, when
1411    /// it answered something this client cannot read, when this client
1412    /// refuses the call before making it because the reason is empty, and
1413    /// when the policy refused the action — which arrives as
1414    /// `ClientError::Rejected`, carrying the reason, the value asked for and
1415    /// the range allowed.
1416    pub fn start_print(
1417        &self,
1418        print_id: &str,
1419        file_name: &FileName,
1420        manifest: &JobManifest,
1421        reason: &str,
1422    ) -> Result<ActionAnswer, ClientError> {
1423        crate::reason_given(reason)?;
1424        let target = format!("/v1/prints/{print_id}/actions/start_print");
1425        let asked: Vec<(String, String)> = Vec::new();
1426        let mut sending = serde_json::Map::new();
1427        sending.insert("actor".to_owned(), crate::as_value(&self.actor())?);
1428        sending.insert("file_name".to_owned(), crate::as_value(&file_name)?);
1429        sending.insert("manifest".to_owned(), crate::as_value(&manifest)?);
1430        sending.insert("reason".to_owned(), crate::as_value(&reason)?);
1431        let sending = Some(serde_json::Value::Object(sending));
1432        self.call("POST", &target, &asked, sending.as_ref())
1433    }
1434
1435    /// Call `set_feedrate_factor` on the configured supervisor.
1436    ///
1437    /// # Errors
1438    ///
1439    /// Returns `ClientError` when the supervisor could not be reached, when
1440    /// it answered something this client cannot read, when this client
1441    /// refuses the call before making it because the reason is empty, and
1442    /// when the policy refused the action — which arrives as
1443    /// `ClientError::Rejected`, carrying the reason, the value asked for and
1444    /// the range allowed.
1445    pub fn set_feedrate_factor(
1446        &self,
1447        print_id: &str,
1448        factor: f64,
1449        reason: &str,
1450        duration_s: Option<i64>,
1451    ) -> Result<ActionAnswer, ClientError> {
1452        crate::reason_given(reason)?;
1453        let target = format!("/v1/prints/{print_id}/actions/set_feedrate_factor");
1454        let asked: Vec<(String, String)> = Vec::new();
1455        let mut sending = serde_json::Map::new();
1456        sending.insert("actor".to_owned(), crate::as_value(&self.actor())?);
1457        if let Some(value) = duration_s {
1458            sending.insert("duration_s".to_owned(), crate::as_value(&value)?);
1459        }
1460        sending.insert("factor".to_owned(), crate::as_value(&factor)?);
1461        sending.insert("reason".to_owned(), crate::as_value(&reason)?);
1462        let sending = Some(serde_json::Value::Object(sending));
1463        self.call("POST", &target, &asked, sending.as_ref())
1464    }
1465
1466    /// Call `set_flowrate_factor` on the configured supervisor.
1467    ///
1468    /// # Errors
1469    ///
1470    /// Returns `ClientError` when the supervisor could not be reached, when
1471    /// it answered something this client cannot read, when this client
1472    /// refuses the call before making it because the reason is empty, and
1473    /// when the policy refused the action — which arrives as
1474    /// `ClientError::Rejected`, carrying the reason, the value asked for and
1475    /// the range allowed.
1476    pub fn set_flowrate_factor(
1477        &self,
1478        print_id: &str,
1479        factor: f64,
1480        reason: &str,
1481        duration_s: Option<i64>,
1482    ) -> Result<ActionAnswer, ClientError> {
1483        crate::reason_given(reason)?;
1484        let target = format!("/v1/prints/{print_id}/actions/set_flowrate_factor");
1485        let asked: Vec<(String, String)> = Vec::new();
1486        let mut sending = serde_json::Map::new();
1487        sending.insert("actor".to_owned(), crate::as_value(&self.actor())?);
1488        if let Some(value) = duration_s {
1489            sending.insert("duration_s".to_owned(), crate::as_value(&value)?);
1490        }
1491        sending.insert("factor".to_owned(), crate::as_value(&factor)?);
1492        sending.insert("reason".to_owned(), crate::as_value(&reason)?);
1493        let sending = Some(serde_json::Value::Object(sending));
1494        self.call("POST", &target, &asked, sending.as_ref())
1495    }
1496
1497    /// Call `set_tool_target_c` on the configured supervisor.
1498    ///
1499    /// # Errors
1500    ///
1501    /// Returns `ClientError` when the supervisor could not be reached, when
1502    /// it answered something this client cannot read, when this client
1503    /// refuses the call before making it because the reason is empty, and
1504    /// when the policy refused the action — which arrives as
1505    /// `ClientError::Rejected`, carrying the reason, the value asked for and
1506    /// the range allowed.
1507    pub fn set_tool_target_c(
1508        &self,
1509        print_id: &str,
1510        reason: &str,
1511        target_c: f64,
1512        tool: i64,
1513        duration_s: Option<i64>,
1514    ) -> Result<ActionAnswer, ClientError> {
1515        crate::reason_given(reason)?;
1516        let target = format!("/v1/prints/{print_id}/actions/set_tool_target_c");
1517        let asked: Vec<(String, String)> = Vec::new();
1518        let mut sending = serde_json::Map::new();
1519        sending.insert("actor".to_owned(), crate::as_value(&self.actor())?);
1520        if let Some(value) = duration_s {
1521            sending.insert("duration_s".to_owned(), crate::as_value(&value)?);
1522        }
1523        sending.insert("reason".to_owned(), crate::as_value(&reason)?);
1524        sending.insert("target_c".to_owned(), crate::as_value(&target_c)?);
1525        sending.insert("tool".to_owned(), crate::as_value(&tool)?);
1526        let sending = Some(serde_json::Value::Object(sending));
1527        self.call("POST", &target, &asked, sending.as_ref())
1528    }
1529
1530    /// Call `set_bed_target_c` on the configured supervisor.
1531    ///
1532    /// # Errors
1533    ///
1534    /// Returns `ClientError` when the supervisor could not be reached, when
1535    /// it answered something this client cannot read, when this client
1536    /// refuses the call before making it because the reason is empty, and
1537    /// when the policy refused the action — which arrives as
1538    /// `ClientError::Rejected`, carrying the reason, the value asked for and
1539    /// the range allowed.
1540    pub fn set_bed_target_c(
1541        &self,
1542        print_id: &str,
1543        reason: &str,
1544        target_c: f64,
1545        duration_s: Option<i64>,
1546    ) -> Result<ActionAnswer, ClientError> {
1547        crate::reason_given(reason)?;
1548        let target = format!("/v1/prints/{print_id}/actions/set_bed_target_c");
1549        let asked: Vec<(String, String)> = Vec::new();
1550        let mut sending = serde_json::Map::new();
1551        sending.insert("actor".to_owned(), crate::as_value(&self.actor())?);
1552        if let Some(value) = duration_s {
1553            sending.insert("duration_s".to_owned(), crate::as_value(&value)?);
1554        }
1555        sending.insert("reason".to_owned(), crate::as_value(&reason)?);
1556        sending.insert("target_c".to_owned(), crate::as_value(&target_c)?);
1557        let sending = Some(serde_json::Value::Object(sending));
1558        self.call("POST", &target, &asked, sending.as_ref())
1559    }
1560
1561    /// Call `set_fan_percent` on the configured supervisor.
1562    ///
1563    /// # Errors
1564    ///
1565    /// Returns `ClientError` when the supervisor could not be reached, when
1566    /// it answered something this client cannot read, when this client
1567    /// refuses the call before making it because the reason is empty, and
1568    /// when the policy refused the action — which arrives as
1569    /// `ClientError::Rejected`, carrying the reason, the value asked for and
1570    /// the range allowed.
1571    pub fn set_fan_percent(
1572        &self,
1573        print_id: &str,
1574        percent: f64,
1575        reason: &str,
1576        duration_s: Option<i64>,
1577    ) -> Result<ActionAnswer, ClientError> {
1578        crate::reason_given(reason)?;
1579        let target = format!("/v1/prints/{print_id}/actions/set_fan_percent");
1580        let asked: Vec<(String, String)> = Vec::new();
1581        let mut sending = serde_json::Map::new();
1582        sending.insert("actor".to_owned(), crate::as_value(&self.actor())?);
1583        if let Some(value) = duration_s {
1584            sending.insert("duration_s".to_owned(), crate::as_value(&value)?);
1585        }
1586        sending.insert("percent".to_owned(), crate::as_value(&percent)?);
1587        sending.insert("reason".to_owned(), crate::as_value(&reason)?);
1588        let sending = Some(serde_json::Value::Object(sending));
1589        self.call("POST", &target, &asked, sending.as_ref())
1590    }
1591
1592    /// Call `acknowledge_failure` on the configured supervisor.
1593    ///
1594    /// # Errors
1595    ///
1596    /// Returns `ClientError` when the supervisor could not be reached, when
1597    /// it answered something this client cannot read, when this client
1598    /// refuses the call before making it because the reason is empty, and
1599    /// when the policy refused the action — which arrives as
1600    /// `ClientError::Rejected`, carrying the reason, the value asked for and
1601    /// the range allowed.
1602    pub fn acknowledge_failure(
1603        &self,
1604        print_id: &str,
1605        disposition: &AcknowledgementDisposition,
1606        event_id: &EventId,
1607        reason: &str,
1608    ) -> Result<ActionAnswer, ClientError> {
1609        crate::reason_given(reason)?;
1610        let target = format!("/v1/prints/{print_id}/actions/acknowledge_failure");
1611        let asked: Vec<(String, String)> = Vec::new();
1612        let mut sending = serde_json::Map::new();
1613        sending.insert("actor".to_owned(), crate::as_value(&self.actor())?);
1614        sending.insert("disposition".to_owned(), crate::as_value(&disposition)?);
1615        sending.insert("event_id".to_owned(), crate::as_value(&event_id)?);
1616        sending.insert("reason".to_owned(), crate::as_value(&reason)?);
1617        let sending = Some(serde_json::Value::Object(sending));
1618        self.call("POST", &target, &asked, sending.as_ref())
1619    }
1620}