fn parse_set_args()

in sources/api/apiclient/src/main.rs [421:497]


fn parse_set_args(args: Vec<String>) -> Subcommand {
    let mut simple = HashMap::new();
    let mut json = None;

    let mut iter = args.into_iter();
    while let Some(arg) = iter.next() {
        match arg.as_ref() {
            "-j" | "--json" if json.is_some() => {
                usage_msg(
                    "Can't specify the --json argument multiple times.  You can set as many \
                     settings as needed within the JSON object.",
                );
            }
            "-j" | "--json" if json.is_none() => {
                let raw_json = iter
                    .next()
                    .unwrap_or_else(|| usage_msg("Did not give argument to -j | --json"));

                let input_val: serde_json::Value =
                    serde_json::from_str(&raw_json).unwrap_or_else(|e| {
                        usage_msg(&format!("Couldn't parse given JSON input: {}", e))
                    });

                let mut input_map = match input_val {
                    serde_json::Value::Object(map) => map,
                    _ => usage_msg("JSON input must be an object (map)"),
                };

                // To be nice, if the user specified a "settings" layer around their data, we
                // remove it.  (This should only happen if there's a single key, since we only
                // allow setting settings; fail otherwise.  If we allow setting other types in the
                // future, we'll have to do more map manipulation here to save the other values.)
                if let Some(val) = input_map.remove("settings") {
                    match val {
                        serde_json::Value::Object(map) => input_map.extend(map),
                        _ => usage_msg("JSON 'settings' value must be an object (map)"),
                    };
                }

                json = Some(input_map.into());
            }

            x if x.contains('=') => {
                let mut split = x.splitn(2, '=');
                let raw_key = split.next().unwrap();
                let value = split.next().unwrap();

                let mut key = Key::new(KeyType::Data, raw_key).unwrap_or_else(|_| {
                    usage_msg(&format!("Given key '{}' is not a valid format", raw_key))
                });

                // Add "settings" prefix if the user didn't give a known prefix, to ease usage
                let key_prefix = &key.segments()[0];
                if key_prefix != "settings" {
                    let mut segments = key.segments().clone();
                    segments.insert(0, "settings".to_string());
                    key = Key::from_segments(KeyType::Data, &segments)
                        .expect("Adding prefix to key resulted in invalid key?!");
                }

                simple.insert(key, value.to_string());
            }

            x => usage_msg(&format!("Unknown argument '{}'", x)),
        }
    }

    if json.is_some() && !simple.is_empty() {
        usage_msg("Cannot specify key=value pairs and --json settings with 'set'");
    } else if let Some(json) = json {
        Subcommand::Set(SetArgs::Json(json))
    } else if !simple.is_empty() {
        Subcommand::Set(SetArgs::Simple(simple))
    } else {
        usage_msg("Must specify key=value settings or --json settings with 'set'");
    }
}