#![allow(clippy::while_let_loop)]
use hippotat::prelude::*;
-use hippotat_macros::into_crlfs;
+
+/// Return a `String` made of each argument followed by CRLF.
+macro_rules! lines_crlf { { $($content:expr),* $(,)? } => {
+ {
+ #[allow(unused_mut)]
+ let mut s = String::new();
+ $(
+ write!(s, "{}\r\n", $content).expect("write failed");
+ )*
+ s
+ }
+} }
+
+/// Displays as the lines of `s`, deindented, with CRLFs
+///
+/// TODO has anomalous handling of the last line.
+pub struct LitLinesCrlf<'s>(pub &'s str);
+
+impl Display for LitLinesCrlf<'_> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let input = &self.0;
+
+ // TODO don't collect
+ // TODO more principled indentation handling
+ let output = input.split_inclusive('\n')
+ .map(|s| s.trim_start_matches(&[' ','\t'][..]))
+ .map(|s| match s.strip_suffix("\n") {
+ None => [s, ""],
+ Some(l) => [l, "\r\n"],
+ })
+ .flatten()
+ .collect::<String>();
+
+ let output = output.strip_suffix("\r\n").expect("XXXX bad input");
+ write!(f, "{output}")
+ }
+}
+
#[derive(clap::Parser,Debug)]
pub struct Opts {
let req_num = { *req_num += 1; *req_num };
- let prefix1 = format!(into_crlfs!(
+ let prefix1 = lines_crlf!(&LitLinesCrlf(
r#"--b
Content-Type: text/plain; charset="utf-8"
Content-Disposition: form-data; name="m"
- {}
- {}
- {}
- {}
- {}
- {}
- {}"#),
+ "#),
&c.ic.link.client,
token,
c.ic.target_requests_outstanding,
c.ic.max_batch_up,
);
- let prefix2 = format!(into_crlfs!(
+ let prefix2 = lines_crlf!(&LitLinesCrlf(
r#"
--b
Content-Type: application/octet-stream
"#),
);
- let suffix = format!(into_crlfs!(
+ let suffix = lines_crlf!(&LitLinesCrlf(
r#"
--b--
"#),
#![allow(clippy::map_flatten)]
#![allow(clippy::single_char_pattern)]
-use syn::LitStr;
-use quote::quote;
-
-#[proc_macro]
-pub fn into_crlfs(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
- let input: proc_macro2::TokenStream = input.into();
- let token: LitStr = syn::parse2(input).expect("expected literal");
- let input = token.value();
- let output = input.split_inclusive('\n')
- .map(|s| s.trim_start_matches(&[' ','\t'][..]))
- .map(|s| match s.strip_suffix("\n") {
- None => [s, ""],
- Some(l) => [l, "\r\n"],
- })
- .flatten()
- .collect::<String>();
- //dbg!(&output);
- let output = LitStr::new(&output, token.span());
- let output = quote!(#output);
- output.into()
-}