(schema: &Map<String, serde_json::Value>, enclosing_ns: &str, in_fields: bool)
| 2380 | } |
| 2381 | |
| 2382 | fn pcf_map(schema: &Map<String, serde_json::Value>, enclosing_ns: &str, in_fields: bool) -> String { |
| 2383 | // Look for the namespace variant up front. |
| 2384 | let default_ns = schema |
| 2385 | .get("namespace") |
| 2386 | .and_then(|v| v.as_str()) |
| 2387 | .unwrap_or(enclosing_ns); |
| 2388 | let mut fields = Vec::new(); |
| 2389 | let mut found_next_ns = None; |
| 2390 | let mut deferred_values = vec![]; |
| 2391 | for (k, v) in schema { |
| 2392 | // Reduce primitive types to their simple form. ([PRIMITIVE] rule) |
| 2393 | if schema.len() == 1 && k == "type" { |
| 2394 | // Invariant: function is only callable from a valid schema, so this is acceptable. |
| 2395 | if let serde_json::Value::String(s) = v { |
| 2396 | return pcf_string(s); |
| 2397 | } |
| 2398 | } |
| 2399 | |
| 2400 | // Strip out unused fields ([STRIP] rule) |
| 2401 | if field_ordering_position(k).is_none() { |
| 2402 | continue; |
| 2403 | } |
| 2404 | |
| 2405 | // Fully qualify the name, if it isn't already ([FULLNAMES] rule). |
| 2406 | if k == "name" { |
| 2407 | // The `fields` stanza needs special handling, as it has "name" |
| 2408 | // fields that don't get canonicalized (since they are not type names). |
| 2409 | if in_fields { |
| 2410 | fields.push(( |
| 2411 | k, |
| 2412 | format!("{}:{}", pcf_string(k), pcf_string(v.as_str().unwrap())), |
| 2413 | )); |
| 2414 | continue; |
| 2415 | } |
| 2416 | // Invariant: Only valid schemas. Must be a string. |
| 2417 | let name = v.as_str().unwrap(); |
| 2418 | assert!( |
| 2419 | found_next_ns.is_none(), |
| 2420 | "`name` must not be specified multiple times" |
| 2421 | ); |
| 2422 | let next_ns = match name.rsplit_once('.') { |
| 2423 | None => default_ns, |
| 2424 | Some((ns, _name)) => ns, |
| 2425 | }; |
| 2426 | found_next_ns = Some(next_ns); |
| 2427 | let n = if next_ns.is_empty() { |
| 2428 | Cow::Borrowed(name) |
| 2429 | } else { |
| 2430 | Cow::Owned(format!("{next_ns}.{name}")) |
| 2431 | }; |
| 2432 | fields.push((k, format!("{}:{}", pcf_string(k), pcf_string(&*n)))); |
| 2433 | continue; |
| 2434 | } |
| 2435 | |
| 2436 | // Strip off quotes surrounding "size" type, if they exist ([INTEGERS] rule). |
| 2437 | if k == "size" { |
| 2438 | let i = match v.as_str() { |
| 2439 | Some(s) => s.parse::<i64>().expect("Only valid schemas are accepted!"), |
no test coverage detected