text - 我怎样才能使用格式! no_std 环境中的宏?

标签 text macros formatting rust embedded

如何在不使用 std 的情况下实现以下示例?

let text = format!("example {:.1} test {:x} words {}", num1, num2, num3);

text 有类型 &strnum1num2num3 有任何类型数字类型。

我试过使用 numtoaitoa/dtoa 来显示数字,但是 numtoa 不支持 float 和 itoa 不支持 no_std。我觉得在字符串中显示数字很常见,而且我可能遗漏了一些明显的东西。

最佳答案

除了Shepmaster's answer您还可以在没有分配器的情况下格式化字符串。

core::fmt::Write你只需要实现write_str,然后你就可以免费获得write_fmt

format_args!(...) (语法与 format! 相同)您可以准备一个 core::fmt::Arguments值,可以传递给 core::fmt::write .

参见 Playground :

#![crate_type = "dylib"]
#![no_std]

pub mod write_to {
    use core::cmp::min;
    use core::fmt;

    pub struct WriteTo<'a> {
        buffer: &'a mut [u8],
        // on write error (i.e. not enough space in buffer) this grows beyond
        // `buffer.len()`.
        used: usize,
    }

    impl<'a> WriteTo<'a> {
        pub fn new(buffer: &'a mut [u8]) -> Self {
            WriteTo { buffer, used: 0 }
        }

        pub fn as_str(self) -> Option<&'a str> {
            if self.used <= self.buffer.len() {
                // only successful concats of str - must be a valid str.
                use core::str::from_utf8_unchecked;
                Some(unsafe { from_utf8_unchecked(&self.buffer[..self.used]) })
            } else {
                None
            }
        }
    }

    impl<'a> fmt::Write for WriteTo<'a> {
        fn write_str(&mut self, s: &str) -> fmt::Result {
            if self.used > self.buffer.len() {
                return Err(fmt::Error);
            }
            let remaining_buf = &mut self.buffer[self.used..];
            let raw_s = s.as_bytes();
            let write_num = min(raw_s.len(), remaining_buf.len());
            remaining_buf[..write_num].copy_from_slice(&raw_s[..write_num]);
            self.used += raw_s.len();
            if write_num < raw_s.len() {
                Err(fmt::Error)
            } else {
                Ok(())
            }
        }
    }

    pub fn show<'a>(buffer: &'a mut [u8], args: fmt::Arguments) -> Result<&'a str, fmt::Error> {
        let mut w = WriteTo::new(buffer);
        fmt::write(&mut w, args)?;
        w.as_str().ok_or(fmt::Error)
    }
}

pub fn test() {
    let mut buf = [0u8; 64];
    let _s: &str = write_to::show(
        &mut buf,
        format_args!("write some stuff {:?}: {}", "foo", 42),
    ).unwrap();
}

关于text - 我怎样才能使用格式! no_std 环境中的宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50200268/

相关文章:

java - 如何在 Java 中设置尊重用户操作系统设置的日期和时间格式

python - 计算多个文件(文本)中的两个值(总单词数和唯一值)并在 Python 中输出 csv

java - 使用 BufferedReader 读取文本文件

recursion - 如何定义与其在 m4 中的扩展同名的宏?

linux - 从已编译的二进制文件中获取宏值(带调试)

formatting - 输出格式 : too much whitespace in gfortran

python - 从字符串中删除所有标点符号,除非它在数字之间

javascript - JS 中的按钮和文本输入

macros - 在 Mathematica 中打印符号名称和值

python - 格式字符串语法 : printing percentage with at least one significant digit