1use crate::TextHandlerImpl;
4use alux_http::{
5 BytesOutAlg, EmptyOutAlg, FileOutAlg, HeaderOutAlg, HtmlOutAlg, HttpErrorAlg, HttpStatus, JsonOutAlg, OutputAlg,
6 RedirectOutAlg, ResultOutAlg, StatusOutAlg, StreamOutAlg, TextOutAlg,
7};
8use core::marker::PhantomData;
9
10macro_rules! text_outputs {
11 ($($output:ident => $alg:ident, $selected:ident, $meaning:literal),+ $(,)?) => {
12 $(
13 #[doc = concat!("Interprets ", $meaning, " output selection in text descriptions.")]
14 pub struct $output;
15
16 impl<From> OutputAlg<From> for $output {
17 type Output = From;
18
19 fn output(from: From) -> From {
20 from
21 }
22 }
23
24 impl $alg for TextHandlerImpl {
25 type $selected<From> = $output;
26 }
27 )+
28 };
29}
30
31text_outputs! {
32 TextJsonOutput => JsonOutAlg, Json, "JSON",
33 TextFileOutput => FileOutAlg, File, "streamed-file",
34 TextTextOutput => TextOutAlg, Text, "plain-text",
35 TextHtmlOutput => HtmlOutAlg, Html, "HTML",
36 TextBytesOutput => BytesOutAlg, Bytes, "raw-byte",
37 TextRedirectOutput => RedirectOutAlg, Redirect, "redirect",
38 TextStreamOutput => StreamOutAlg, Stream, "streamed",
39}
40
41pub struct TextEmptyOutput;
46
47impl OutputAlg<()> for TextEmptyOutput {
48 type Output = ();
49
50 fn output((): ()) {}
51}
52
53impl EmptyOutAlg for TextHandlerImpl {
54 type Empty<From> = TextEmptyOutput;
55}
56
57pub struct TextHeaderOutput<Inner, Name>(PhantomData<fn(Inner, Name)>);
59
60impl<Inner, Name, Value, Rest> OutputAlg<(Value, Rest)> for TextHeaderOutput<Inner, Name>
61where
62 Inner: OutputAlg<Rest>,
63{
64 type Output = Inner::Output;
65
66 fn output((_value, rest): (Value, Rest)) -> Self::Output {
67 Inner::output(rest)
68 }
69}
70
71impl HeaderOutAlg for TextHandlerImpl {
72 type Header<Inner, Name> = TextHeaderOutput<Inner, Name>;
73}
74
75pub struct TextStatusOutput<Inner, const CODE: u16>(PhantomData<Inner>);
77
78impl<Inner, From, const CODE: u16> OutputAlg<From> for TextStatusOutput<Inner, CODE>
79where
80 Inner: OutputAlg<From>,
81{
82 type Output = Inner::Output;
83
84 fn output(from: From) -> Self::Output {
85 Inner::output(from)
86 }
87}
88
89impl StatusOutAlg for TextHandlerImpl {
90 type Status<Inner, const CODE: u16> = TextStatusOutput<Inner, CODE>;
91}
92
93pub struct TextResultOutput<Inner, Error>(PhantomData<fn(Inner, Error)>);
98
99impl<Inner, Error, Value> OutputAlg<Result<Value, Error>> for TextResultOutput<Inner, Error>
100where
101 Inner: OutputAlg<Value>,
102 Error: HttpErrorAlg,
103{
104 type Output = Result<Inner::Output, HttpStatus>;
105
106 fn output(from: Result<Value, Error>) -> Self::Output {
107 from.map(Inner::output).map_err(|error| error.http_status())
108 }
109}
110
111impl ResultOutAlg for TextHandlerImpl {
112 type Result<Inner, Error> = TextResultOutput<Inner, Error>;
113}