1use std::fmt::Display;
2
3use kdl::{KdlEntry, KdlNode};
4use serde::Serialize;
5
6use crate::error::Result;
7use crate::spec::context::ParsingContext;
8use crate::spec::helpers::{string_entry, NodeHelper};
9
10#[derive(Debug, Default, Clone, Serialize)]
11#[non_exhaustive]
12pub struct SpecMount {
13 pub run: String,
14 pub overrides_default: bool,
23}
24
25impl SpecMount {
26 pub fn new(run: impl Into<String>) -> Self {
28 Self {
29 run: run.into(),
30 overrides_default: false,
31 }
32 }
33
34 pub fn overriding_default(run: impl Into<String>) -> Self {
36 Self {
37 run: run.into(),
38 overrides_default: true,
39 }
40 }
41}
42
43impl SpecMount {
44 pub(crate) fn parse(ctx: &ParsingContext, node: &NodeHelper) -> Result<Self> {
45 let mut mount = SpecMount::default();
46 for (k, v) in node.props() {
47 match k {
48 "run" => mount.run = v.ensure_string()?,
49 "overrides_default" => mount.overrides_default = v.ensure_bool()?,
50 k => bail_parse!(ctx, v.entry.span(), "unsupported mount key {k}"),
51 }
52 }
53 for child in node.children() {
54 match child.name() {
55 "run" => mount.run = child.arg(0)?.ensure_string()?,
56 "overrides_default" => mount.overrides_default = child.arg(0)?.ensure_bool()?,
57 k => bail_parse!(
58 ctx,
59 child.node.name().span(),
60 "unsupported mount value key {k}"
61 ),
62 }
63 }
64 if mount.run.is_empty() {
65 bail_parse!(ctx, node.span(), "mount run is required")
66 }
67 Ok(mount)
68 }
69 pub fn usage(&self) -> String {
70 format!("mount:{}", self.run)
71 }
72}
73
74impl From<&SpecMount> for KdlNode {
75 fn from(mount: &SpecMount) -> KdlNode {
76 let mut node = KdlNode::new("mount");
77 node.push(string_entry(Some("run"), &mount.run));
78 if mount.overrides_default {
79 node.push(KdlEntry::new_prop("overrides_default", true));
80 }
81 node
82 }
83}
84
85impl Display for SpecMount {
86 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87 write!(f, "{}", self.usage())
88 }
89}