fn from_str()

in reverie-process/src/mount.rs [400:488]


    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut map: HashMap<&str, Option<&str>> = HashMap::new();

        for item in s.split(',') {
            let item = item.trim();

            if item.is_empty() {
                continue;
            }

            let (key, value) = match item.split_once('=') {
                Some((key, value)) => (key, Some(value)),
                None => (item, None),
            };

            map.insert(key, value);
        }

        // The mount target is always required.
        let mut mount = match map
            .remove("target")
            .or_else(|| map.remove("destination"))
            .or_else(|| map.remove("dest"))
            .or_else(|| map.remove("dst"))
            .flatten()
        {
            Some(target) => Mount::new(target),
            None => {
                return Err(MountParseError::MissingTarget);
            }
        };

        if let Some(source) = map.remove("source").or_else(|| map.remove("src")).flatten() {
            mount = mount.source(source);
        }

        let is_bind_mount = if let Some(fstype) = map.remove("type").flatten() {
            if fstype == "bind" {
                true
            } else {
                mount = mount.fstype(fstype);
                false
            }
        } else {
            true
        };

        if is_bind_mount {
            mount = mount.flags(MountFlags::MS_BIND);
        }

        if let Some((key, value)) = map.remove_entry("readonly") {
            if let Some(value) = value {
                // No value should have been specified.
                return Err(MountParseError::Invalid(key.into(), Some(value.to_owned())));
            }

            mount = mount.readonly();
        }

        if let Some(propagation) = map.remove("bind-propagation").flatten() {
            let flags = match propagation {
                "shared" => MountFlags::MS_SHARED,
                "slave" => MountFlags::MS_SLAVE,
                "private" => MountFlags::MS_PRIVATE,
                "rshared" => MountFlags::MS_REC | MountFlags::MS_SHARED,
                "rslave" => MountFlags::MS_REC | MountFlags::MS_SLAVE,
                "rprivate" => MountFlags::MS_REC | MountFlags::MS_PRIVATE,
                _ => {
                    return Err(MountParseError::Invalid(
                        "bind-propagation".into(),
                        Some(propagation.into()),
                    ));
                }
            };

            mount = mount.flags(flags);
        } else {
            // All mounts get these flags by default.
            mount = mount.flags(MountFlags::MS_REC | MountFlags::MS_PRIVATE);
        }

        // Any left over keys are invalid.
        if let Some((k, v)) = map.into_iter().next() {
            return Err(MountParseError::Invalid(k.into(), v.map(ToOwned::to_owned)));
        }

        Ok(mount)
    }