progenitor/progenitor-impl/src/util.rs

87 lines
2.3 KiB
Rust
Raw Normal View History

// Copyright 2022 Oxide Computer Company
use convert_case::{Case, Casing};
use indexmap::IndexMap;
use openapiv3::{
Components, Parameter, ReferenceOr, RequestBody, Response, Schema,
};
use unicode_xid::UnicodeXID;
use crate::Result;
pub(crate) trait ReferenceOrExt<T: ComponentLookup> {
fn item<'a>(&'a self, components: &'a Option<Components>) -> Result<&'a T>;
}
pub(crate) trait ComponentLookup: Sized {
fn get_components(
components: &Components,
) -> &IndexMap<String, ReferenceOr<Self>>;
}
impl<T: ComponentLookup> ReferenceOrExt<T> for openapiv3::ReferenceOr<T> {
fn item<'a>(&'a self, components: &'a Option<Components>) -> Result<&'a T> {
match self {
ReferenceOr::Item(item) => Ok(item),
ReferenceOr::Reference { reference } => {
let idx = reference.rfind('/').unwrap();
let key = &reference[idx + 1..];
let parameters =
T::get_components(components.as_ref().unwrap());
parameters.get(key).unwrap().item(components)
}
}
}
}
impl ComponentLookup for Parameter {
fn get_components(
components: &Components,
) -> &IndexMap<String, ReferenceOr<Self>> {
&components.parameters
}
}
impl ComponentLookup for RequestBody {
fn get_components(
components: &Components,
) -> &IndexMap<String, ReferenceOr<Self>> {
&components.request_bodies
}
}
impl ComponentLookup for Response {
fn get_components(
components: &Components,
) -> &IndexMap<String, ReferenceOr<Self>> {
&components.responses
}
}
impl ComponentLookup for Schema {
fn get_components(
components: &Components,
) -> &IndexMap<String, ReferenceOr<Self>> {
&components.schemas
}
}
pub(crate) fn sanitize(input: &str, case: Case) -> String {
let out = input
.replace("'", "")
.replace(|c: char| !c.is_xid_continue(), "-")
.to_case(case);
let out = match out.chars().next() {
None => "x".to_case(case),
Some(c) if c.is_xid_start() => out,
Some(_) => format!("_{}", out),
};
// Make sure the string is a valid Rust identifier.
if syn::parse_str::<syn::Ident>(&out).is_ok() {
out
} else {
format!("{}_", out)
}
}