topcoat_openapi/
content.rs1use schemars::{JsonSchema, Schema, SchemaGenerator};
2use topcoat_router::content::{Form, Json};
3
4pub trait Content {
29 const MEDIA_TYPE: &'static str;
31
32 const REQUIRED: bool = true;
34
35 fn schema(generator: &mut SchemaGenerator) -> Schema;
41}
42
43impl<T: JsonSchema> Content for Json<T> {
44 const MEDIA_TYPE: &'static str = "application/json";
45
46 fn schema(generator: &mut SchemaGenerator) -> Schema {
47 generator.subschema_for::<T>()
48 }
49}
50
51impl<T: JsonSchema> Content for Form<T> {
52 const MEDIA_TYPE: &'static str = "application/x-www-form-urlencoded";
53
54 fn schema(generator: &mut SchemaGenerator) -> Schema {
55 generator.subschema_for::<T>()
56 }
57}
58
59impl Content for String {
60 const MEDIA_TYPE: &'static str = "text/plain";
61
62 fn schema(generator: &mut SchemaGenerator) -> Schema {
63 generator.subschema_for::<String>()
64 }
65}
66
67impl Content for &str {
68 const MEDIA_TYPE: &'static str = "text/plain";
69
70 fn schema(generator: &mut SchemaGenerator) -> Schema {
71 generator.subschema_for::<String>()
72 }
73}
74
75impl<T: Content> Content for Option<T> {
77 const MEDIA_TYPE: &'static str = T::MEDIA_TYPE;
78 const REQUIRED: bool = false;
79
80 fn schema(generator: &mut SchemaGenerator) -> Schema {
81 T::schema(generator)
82 }
83}
84
85pub(crate) type SchemaFn = fn(&mut SchemaGenerator) -> Schema;
87
88#[derive(Debug, Clone, Copy)]
90pub(crate) struct ContentType {
91 pub(crate) media_type: &'static str,
92 pub(crate) required: bool,
93 pub(crate) schema: SchemaFn,
94}
95
96impl ContentType {
97 pub(crate) fn of<T: Content>() -> Self {
99 Self {
100 media_type: T::MEDIA_TYPE,
101 required: T::REQUIRED,
102 schema: T::schema,
103 }
104 }
105}