fn pcf_map()

in avro/src/schema.rs [2317:2398]


fn pcf_map(schema: &Map<String, Value>, defined_names: &mut HashSet<String>) -> String {
    // Look for the namespace variant up front.
    let ns = schema.get("namespace").and_then(|v| v.as_str());
    let typ = schema.get("type").and_then(|v| v.as_str());
    let raw_name = schema.get("name").and_then(|v| v.as_str());
    let name = if is_named_type(typ) {
        Some(format!(
            "{}{}",
            ns.map_or("".to_string(), |n| { format!("{n}.") }),
            raw_name.unwrap_or_default()
        ))
    } else {
        None
    };

    //if this is already a defined type, early return
    if let Some(ref n) = name {
        if defined_names.contains(n) {
            return pcf_string(n);
        } else {
            defined_names.insert(n.clone());
        }
    }

    let mut fields = Vec::new();
    for (k, v) in schema {
        // Reduce primitive types to their simple form. ([PRIMITIVE] rule)
        if schema.len() == 1 && k == "type" {
            // Invariant: function is only callable from a valid schema, so this is acceptable.
            if let Value::String(s) = v {
                return pcf_string(s);
            }
        }

        // Strip out unused fields ([STRIP] rule)
        if field_ordering_position(k).is_none()
            || k == "default"
            || k == "doc"
            || k == "aliases"
            || k == "logicalType"
        {
            continue;
        }

        // Fully qualify the name, if it isn't already ([FULLNAMES] rule).
        if k == "name" {
            if let Some(ref n) = name {
                fields.push(("name", format!("{}:{}", pcf_string(k), pcf_string(n))));
                continue;
            }
        }

        // Strip off quotes surrounding "size" type, if they exist ([INTEGERS] rule).
        if k == "size" || k == "precision" || k == "scale" {
            let i = match v.as_str() {
                Some(s) => s.parse::<i64>().expect("Only valid schemas are accepted!"),
                None => v.as_i64().unwrap(),
            };
            fields.push((k, format!("{}:{}", pcf_string(k), i)));
            continue;
        }

        // For anything else, recursively process the result.
        fields.push((
            k,
            format!(
                "{}:{}",
                pcf_string(k),
                parsing_canonical_form(v, defined_names)
            ),
        ));
    }

    // Sort the fields by their canonical ordering ([ORDER] rule).
    fields.sort_unstable_by_key(|(k, _)| field_ordering_position(k).unwrap());
    let inter = fields
        .into_iter()
        .map(|(_, v)| v)
        .collect::<Vec<_>>()
        .join(",");
    format!("{{{inter}}}")
}