pub(crate) mod dotnet;
pub(crate) mod go;
pub(crate) mod java;
pub(crate) mod python;
pub(crate) mod typescript;
pub(in crate::generator) use crate::planning::build_json_name_manifest;
use std::collections::BTreeMap;
use crate::planning::{PlannedJsonType, PlannedSpec};
pub(in crate::generator) fn bare_ref_target(model: &PlannedJsonType) -> Option<&str> {
let object = model.schema.as_object()?;
object
.iter()
.all(|(key, value)| key == "$ref" || value.is_null())
.then(|| object.get("$ref")?.as_str())
.flatten()
}
pub(in crate::generator) fn register_cross_module_ref_names(
api_plan: &PlannedSpec,
ref_names: &mut BTreeMap<String, String>,
) {
for (full_name, model_name) in &api_plan.data.cross_module_model_names {
ref_names.insert(full_name.clone(), model_name.clone());
ref_names.insert(format!("#/$defs/{full_name}"), model_name.clone());
}
}
pub(in crate::generator) fn violation_member_segment(key: &str) -> String {
let mut bytes = key.bytes();
let identifier = bytes
.next()
.is_some_and(|byte| byte == b'_' || byte.is_ascii_alphabetic())
&& bytes.all(|byte| byte == b'_' || byte.is_ascii_alphanumeric());
if identifier {
return key.to_string();
}
let escaped = key.replace('\\', "\\\\").replace('"', "\\\"");
format!("[\"{escaped}\"]")
}
#[cfg(test)]
mod tests {
use super::violation_member_segment;
#[test]
fn violation_member_segments_follow_the_public_path_grammar() {
assert_eq!(violation_member_segment("plain_name9"), "plain_name9");
assert_eq!(violation_member_segment("9lives"), "[\"9lives\"]");
assert_eq!(violation_member_segment("a.b"), "[\"a.b\"]");
assert_eq!(violation_member_segment("[0]"), "[\"[0]\"]");
assert_eq!(
violation_member_segment("quote\"slash\\"),
"[\"quote\\\"slash\\\\\"]"
);
assert_eq!(violation_member_segment(""), "[\"\"]");
assert_eq!(violation_member_segment("café"), "[\"café\"]");
}
}