use crate::model::{Field, Type};
use convert_case::{Case, Casing};
use eyre::{ContextCompat, Result};
use serde::*;
use std::fmt::Write;
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
pub struct EndpointSchema {
pub name: String,
pub code: u32,
pub parameters: Vec<Field>,
pub returns: Vec<Field>,
#[serde(default)]
pub stream_response: Option<Type>,
#[serde(default)]
pub description: String,
#[serde(default)]
pub json_schema: serde_json::Value,
pub roles: Vec<String>,
}
impl EndpointSchema {
pub fn new(
name: impl Into<String>,
code: u32,
parameters: Vec<Field>,
returns: Vec<Field>,
) -> Self {
Self {
name: name.into(),
code,
parameters,
returns,
stream_response: None,
description: "".to_string(),
json_schema: Default::default(),
roles: Vec::new(),
}
}
pub fn with_stream_response_type(mut self, stream_response: Type) -> Self {
self.stream_response = Some(stream_response);
self
}
pub fn with_description(mut self, desc: impl Into<String>) -> Self {
self.description = desc.into();
self
}
pub fn with_roles(mut self, roles: Vec<String>) -> Self {
self.roles = roles;
self
}
}
pub fn encode_header<T: Serialize>(v: T, schema: EndpointSchema) -> Result<String> {
let mut s = String::new();
write!(s, "0{}", schema.name.to_ascii_lowercase())?;
let v = serde_json::to_value(&v)?;
for (i, f) in schema.parameters.iter().enumerate() {
let key = f.name.to_case(Case::Camel);
let value = v.get(&key).with_context(|| format!("key: {key}"))?;
if value.is_null() {
continue;
}
write!(
s,
", {}{}",
i + 1,
urlencoding::encode(&value.to_string().replace('\"', ""))
)?;
}
Ok(s)
}