fn from_str()

in core/cli/src/args/permissions/stream.rs [113:197]


    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut p = s.split('#');

        let stream_part = match p.next() {
            Some(part) => part,
            None => return Err("Missing stream permissions part".to_string()),
        };

        let mut parts = stream_part.split(':');
        let stream_id = parts
            .next()
            .ok_or("Missing stream ID".to_string())
            .and_then(|id| {
                id.parse()
                    .map_err(|error| format!("Invalid stream ID - {}", error))
            })?;

        let (stream_permissions, stream_errors): (Vec<StreamPermission>, Option<String>) =
            match parts.next() {
                Some(permissions_str) => {
                    let (values, errors): (Vec<_>, Vec<_>) = permissions_str
                        .split(',')
                        .map(|s| s.parse::<StreamPermission>())
                        .partition(Result::is_ok);

                    let error = if !errors.is_empty() {
                        let errors = errors
                            .into_iter()
                            .map(|e| format!("\"{}\"", e.err().unwrap().0))
                            .collect::<Vec<String>>();

                        Some(format!(
                            "Unknown permission{} {} for stream ID: {}",
                            match errors.len() {
                                1 => "",
                                _ => "s",
                            },
                            errors.join(", "),
                            stream_id
                        ))
                    } else {
                        None
                    };

                    (values.into_iter().map(|p| p.unwrap()).collect(), error)
                }
                None => (vec![], None),
            };

        let (topic_permissions, topic_errors): (Vec<TopicPermissionsArg>, Option<String>) = {
            let (permissions, errors): (Vec<_>, Vec<_>) = p
                .map(|s| s.parse::<TopicPermissionsArg>())
                .partition(Result::is_ok);

            let errors = if !errors.is_empty() {
                Some(
                    errors
                        .into_iter()
                        .map(|e| e.err().unwrap())
                        .collect::<Vec<String>>()
                        .join("; "),
                )
            } else {
                None
            };

            (
                permissions.into_iter().map(|p| p.unwrap()).collect(),
                errors,
            )
        };

        match (stream_errors, topic_errors) {
            (Some(e), Some(f)) => return Err(format!("{}; {}", e, f)),
            (Some(e), None) => return Err(e),
            (None, Some(f)) => return Err(f),
            (None, None) => (),
        }

        Ok(StreamPermissionsArg::new(
            stream_id,
            stream_permissions,
            topic_permissions,
        ))
    }