format-bytes 0.4.0

A macro to format bytestrings
Documentation
//! Simple test where compiler error reporting is nicer than in doctests.

use format_bytes::format_bytes;

#[test]
fn smoke_test() {
    // Exercise different code paths of the proc macro
    assert_eq!(format_bytes!(b""), b"");
    assert_eq!(format_bytes!(b"foo"), b"foo");
    assert_eq!(format_bytes!(b"{}", b"foo"), b"foo");
    assert_eq!(format_bytes!(b"f{}", b"oo"), b"foo");
    assert_eq!(format_bytes!(b"{}oo", b"f"), b"foo");
    assert_eq!(format_bytes!(b"{{}}"), b"{}");
    assert_eq!(format_bytes!(b"}}{}{{", b"foo"), b"}foo{");

    // Captures from scope, each evaluated once
    let rev = 42;
    assert_eq!(format_bytes!("{}: rev {rev}, {rev}", 1), b"1: rev 42, 42");
    assert_eq!(format_bytes!("{rev}{a}{}", 1, a = b"x"), b"42x1");
    assert_eq!(format_bytes!("{rev}", rev = 1), b"1");

    let unsized_arg: &[u8] = b"foo";
    assert_eq!(format_bytes!("{}", *unsized_arg), b"foo");

    let output = b"o";
    let mut out = vec![];
    format_bytes::write_bytes!(&mut out, b"{}", output).unwrap();
    assert_eq!(out, b"o");
}

mod shadowed {
    /// Generated code must not resolve to this.
    #[allow(dead_code)]
    mod format_bytes {}

    #[test]
    fn crate_path() {
        assert_eq!(::format_bytes::format_bytes!(b"{}", b"foo"), b"foo");
    }
}

#[test]
fn join_is_reusable() {
    let joined = format_bytes::join([1, 2], b",");
    assert_eq!(format_bytes!(b"{} {}", &joined, &joined), b"1,2 1,2");
    fn send_sync(_: &(impl Send + Sync)) {}
    send_sync(&joined);
}

#[test]
fn arguments_are_evaluated_before_writing() {
    struct Failing;

    impl std::io::Write for Failing {
        fn write(&mut self, _: &[u8]) -> std::io::Result<usize> {
            Err(std::io::ErrorKind::Other.into())
        }

        fn flush(&mut self) -> std::io::Result<()> {
            Ok(())
        }
    }

    let mut evaluated = 0;
    let result = format_bytes::write_bytes!(&mut Failing, b"x{}", {
        evaluated += 1;
        1
    });
    assert!(result.is_err());
    assert_eq!(evaluated, 1);
}