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}