JBZGFYVOKR3X2GH25SOOW3X7RKY6ZACESYFF5NO26PJFUP3XGXUAC
/// Parser
#[cfg(feature = "parsers")]
pub mod parse {
use nom::{bytes::complete::take, combinator::map_res, error::context, IResult};
use super::*;
/// A simple `nom` parser for Gemini statuses based on `Status::from_bytes`.
pub fn status(input: &[u8]) -> IResult<&[u8], Status> {
context("status code", map_res(take(2usize), Status::from_bytes))(input)
}
}
/// Return the response body as a utf-8 string, if present.
/// Return the response body as a string, if present and valid utf-8.
///
/// If you wish to allow invalid utf-8, call `body_bytes` and use the
/// appropriate `String` function.
}
}
/// Parser
#[cfg(feature = "parsers")]
pub mod parse {
use nom::{
combinator::{map_opt, rest},
error::context,
sequence::pair,
IResult,
};
use super::*;
use crate::header::parse::header;
/// A `nom` parser for a response. Any bytes after the CRLF that separates
/// the header from the response body will be considered part of the body.
pub fn response(input: &[u8]) -> IResult<&[u8], Response> {
context(
"response",
map_opt(pair(header, rest), |t| {
if t.1.is_empty() {
Response::new(t.0, None)
} else {
let v = Vec::from(t.1);
Response::new(t.0, Some(v))
}
}),
)(input)
}
}
/// Parser
#[cfg(feature = "parsers")]
pub mod parse {
use std::str;
use nom::{
bytes::complete::{tag, take_until},
combinator::map_res,
error::context,
sequence::terminated,
IResult,
};
use super::*;
/// `nom` parser for a request string. Invalid utf-8 will be rejected, but
/// non-"gemini://" urls are allowed as per the spec.
pub fn request(input: &[u8]) -> IResult<&[u8], Request> {
context(
"request",
map_res(terminated(take_until("\r\n"), tag("\r\n")), |bs| {
let s = str::from_utf8(bs).map_err(|_| InvalidRequest::new())?;
Request::from_uri(s)
}),
)(input)
#[cfg(feature = "parsers")]
mod parse {
use nom::{error::Error, Finish};
use paste::paste;
use crate::{header, request, response, status};
macro_rules! parsers {
($(
$(#[$doc:meta])*
$name:ident: $type:ident
),*) => {
$(
paste! {
$(#[$doc])*
pub fn [< parse_ $name >]<'i>(input: impl AsRef<[u8]> + 'i) -> Result<$name::$type, Error<Vec<u8>>> {
let bytes = input.as_ref();
match $name::parse::$name(bytes).finish() {
Ok((_, res)) => Ok(res),
Err(Error { input, code }) => Err({
let input = input.to_owned();
Error { input, code }
})
}
}
}
)*
};
}
parsers!(
/// Parse a `Header` from bytes.
header: Header,
/// Parse a `Request` from bytes.
request: Request,
/// Parse a `Response` from bytes.
response: Response,
/// Parse a `Status` from bytes.
status: Status
);
}
pub use parse::{parse_header, parse_request, parse_response, parse_status};
/// Parser
#[cfg(feature = "parsers")]
pub mod parse {
use nom::{
bytes::complete::{tag, take_until},
combinator::{map_opt, map_res},
error::context,
sequence::{terminated, tuple},
IResult,
};
use super::*;
use crate::status::parse::status;
/// A `nom` parser for response headers. Fails on invalid utf-8.
pub fn header(input: &[u8]) -> IResult<&[u8], Header> {
let meta = map_res(take_until("\r\n"), |bs| {
let v = Vec::from(bs);
String::from_utf8(v)
});
context(
"response header",
map_opt(
tuple((terminated(status, tag(" ")), terminated(meta, tag("\r\n")))),
|t| Header::new(t.0, t.1),
),
)(input)
}
}
nom = { version = "6.0.1", optional = true }
paste = { version = "1.0.4", optional = true }
[[package]]
name = "wyz"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"