1use std::fmt::Display;
2
3use kdl::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}
15
16impl SpecMount {
17 pub fn new(run: impl Into<String>) -> Self {
19 Self { run: run.into() }
20 }
21}
22
23impl SpecMount {
24 pub(crate) fn parse(ctx: &ParsingContext, node: &NodeHelper) -> Result<Self> {
25 let mut mount = SpecMount::default();
26 for (k, v) in node.props() {
27 match k {
28 "run" => mount.run = v.ensure_string()?,
29 k => bail_parse!(ctx, v.entry.span(), "unsupported mount key {k}"),
30 }
31 }
32 for child in node.children() {
33 match child.name() {
34 "run" => mount.run = child.arg(0)?.ensure_string()?,
35 k => bail_parse!(
36 ctx,
37 child.node.name().span(),
38 "unsupported mount value key {k}"
39 ),
40 }
41 }
42 if mount.run.is_empty() {
43 bail_parse!(ctx, node.span(), "mount run is required")
44 }
45 Ok(mount)
46 }
47 pub fn usage(&self) -> String {
48 format!("mount:{}", self.run)
49 }
50}
51
52impl From<&SpecMount> for KdlNode {
53 fn from(mount: &SpecMount) -> KdlNode {
54 let mut node = KdlNode::new("mount");
55 node.push(string_entry(Some("run"), &mount.run));
56 node
57 }
58}
59
60impl Display for SpecMount {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 write!(f, "{}", self.usage())
63 }
64}