1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#![deny(
missing_debug_implementations,
missing_docs,
missing_copy_implementations
)]
#![forbid(unsafe_code)]
pub mod gemtext;
pub mod header;
pub mod request;
pub mod response;
pub mod status;
pub use gemtext::{Builder, Doc, Level};
pub use header::{Header, MetaKind};
pub use request::{AnyRequest, GeminiRequest, InvalidRequest, Request, Url};
pub use response::Response;
pub use status::{Category, Code, InvalidStatusCode, Status};
#[cfg(feature = "parsers")]
pub mod parse {
use nom::{error::Error, Finish};
use paste::paste;
pub use nom::Err;
use crate::{gemtext, header, request, response, status};
macro_rules! parsers {
($(
$(#[$doc:meta])*
$name:ident: $type:ident
),*) => {
$(
paste! {
$(#[$doc])*
pub fn [< parse_ $name >](input: impl AsRef<[u8]>) -> Result<$name::$type, Error<String>> {
let bytes = input.as_ref();
match $name::parse::$name(bytes).finish() {
Ok((_, res)) => Ok(res),
Err(Error { input, code }) => Err({
let bytes = input.to_owned();
let input = String::from_utf8_lossy(&bytes).to_string();
Error { input, code }
})
}
}
}
)*
};
}
parsers!(
header: Header,
request: AnyRequest,
response: Response,
status: Status
);
pub fn parse_gemtext(input: impl AsRef<str>) -> Result<gemtext::Builder, Error<String>> {
let input = input.as_ref();
match gemtext::parse::document(input).finish() {
Ok((_, res)) => Ok(res),
Err(Error { input, code }) => Err({
let input = input.to_string();
Error { input, code }
}),
}
}
}