5个版本 (3个破坏性版本)

0.4.1 2024年1月3日
0.4.0 2024年1月1日
0.3.0 2023年2月12日
0.2.0 2022年7月1日
0.1.0 2022年4月15日

#35 in 值格式化

Download history 7/week @ 2024-07-01 89/week @ 2024-07-29

每月89次下载

MIT/Apache

1.5MB
37K SLoC

debug3

A space effiecent replacement for std::fmt::Debug

简介

假设你有这样的数据

let complex_structure = vec![
        vec![None, Some(2)],
        vec![Some(2), None],
        vec![Some(4), Some(777)],
        vec![None, Some(2)],
        vec![Some(2), None],
        vec![None, None, None, None, None],
];

并且你想将其格式化为字符串。你可以使用 format!, complex_structure) 和得到如下结果

[[None, Some(2)], [Some(2), None], [Some(4), Some(777)], [None, Some(2)], [Some(2), None], [None, None, None, None, None]]

但是这行太长了,难以阅读。对于更大的结构,问题会更严重。

幸运的是有另一种选择 format!, complex_structure),它给出了

[
    [
        None,
        Some(
            2,
        ),
    ],
    [
        Some(
            2,
        ),
        None,
    ],
    [
        Some(
            4,
        ),
        Some(
            777,
        ),
    ],
    [
        None,
        Some(
            2,
        ),
    ],
    [
        Some(
            2,
        ),
        None,
    ],
    [
        None,
        None,
        None,
        None,
        None,
    ],
]

这有一个相反的问题,即它占用了太多的空间,即使代码可以更紧密地包装。

debug3 提供了第三个选项,它比 :#? 更密集,但比 :? 更易于阅读。如果你使用 debug3::pprint, complex_structure),你将得到

[
    [None, Some(2)],
    [Some(2), None],
    [Some(4), Some(777)],
    [None, Some(2)],
    [Some(2), None],
    [None, None, None, None, None],
]

概述

主要入口点是 Debug 特性,它是 std::fmt::Debug 的等价物,具有相似的API。

这可以是#[derive]实现的,或者手动实现。

use debug3::{Debug, Formatter, pprint};

#[derive(Debug)]
struct MyStruct {
    a: i32,
    b: i32,
}

struct AnotherStruct {
    a: i32,
    b: i32,
}

impl Debug for AnotherStruct {
    fn fmt(&self, f: &mut Formatter) {
        f.debug_struct("AnotherStruct")
            .field("a", &self.a)
            .field("b", &self.b)
            .finish()
    }
}

assert_eq!(pprint(MyStruct { a: 1, b: 2 }), "MyStruct { a: 1, b: 2 }");
assert_eq!(pprint(AnotherStruct { a: 1, b: 2 }), "AnotherStruct { a: 1, b: 2 }");

一旦您的类型实现了Debug,您有几种格式化它的选项

std::fmt::Debug的比较

尽管debug3的主要优势是输出质量较高,但它与std::fmt相比存在一些缺点,您应该了解

  1. 通用性:Rust中的几乎所有类型都实现了std::fmt::Debug,而几乎没有类型在[std]之外实现了debug3::Debug
  2. 可用性:std::fmt也作为core::fmt提供,这允许您在no_std环境中使用它。由于debug3需要几个分配的数据结构,因此不能支持这些环境。
  3. 灵活性:std::fmt::Formatter为实现std::fmt::Debug提供了更多的API。为了实现良好的格式化,我们无法接受任意字符串,而必须以结构体、元组、映射、列表和集合的形式提供项目。
  4. 可配置性:我们不支持类似format!("{:x?}, 1)的功能来配置数字的打印方式。
  5. 易用性:我们没有类似std::format的宏来轻松地从实现Debug的几个元素创建字符串。

先例

debug3不可能没有以下所有优秀的工作

许可证

根据您的选择,在 Apache License, Version 2.0MIT 许可证 下获得许可。
除非您明确声明,否则根据 Apache-2.0 许可证定义的任何贡献,均应按照上述双重许可,不附加任何额外的条款或条件。

依赖关系

~0.4–23MB
~302K SLoC