3个不稳定版本

0.2.0 2024年4月23日
0.1.1 2023年9月25日
0.1.0 2023年9月16日

135值格式化 中排名

Download history 30/week @ 2024-03-13 24/week @ 2024-03-20 25/week @ 2024-03-27 48/week @ 2024-04-03 89/week @ 2024-04-10 155/week @ 2024-04-17 47/week @ 2024-04-24 29/week @ 2024-05-01 30/week @ 2024-05-08 32/week @ 2024-05-15 12/week @ 2024-05-22 23/week @ 2024-05-29 160/week @ 2024-06-05 7/week @ 2024-06-12 26/week @ 2024-06-19 11/week @ 2024-06-26

208 每月下载量
3 crates 中使用

MIT 许可证

36KB
325

tiny_pretty

Crates.io docs.rs

Wadler风格美化打印算法的轻量级实现,包含一些高级选项,如控制换行和缩进类型。

有关教程和API文档,请参阅 docs.rs

致谢

许可证

MIT许可证

版权所有 (c) 2023-至今 Pig Fang


lib.rs:

Wadler风格美化打印算法的轻量级实现。

基本用法

假设我们要打印一个函数调用的代码片段,并且我们已经定义了如下数据结构

struct FunctionCall {
    name: String,
    args: Vec<FunctionCall>,
}

我们可能有一个非常非常长的函数调用,因此我们需要美化打印以提高可读性。我们的函数调用可能像这样

let fn_call = FunctionCall {
    name: "foo".into(),
    args: vec![
        FunctionCall { name: "really_long_arg".into(), args: vec![] },
        FunctionCall { name: "omg_so_many_parameters".into(), args: vec![] },
        FunctionCall { name: "we_should_refactor_this".into(), args: vec![] },
        FunctionCall { name: "is_there_seriously_another_one".into(), args: vec![] },
    ],
};

(此示例从 Prettier 复制而来,并进行了修改。)

现在我们将实现从上述数据结构构建 [Doc] 的功能。我们期望参数应尽可能放在同一行上。如果它们太长而无法适应,我们将插入带有缩进的换行。

  • 当在单行时,左括号和右括号之间没有空格,并且每个参数逗号后面必须有一个空格。
  • 当拆分成不同的行时,打印参数时必须缩进,并且参数之间必须有一个换行符。

因此,我们可以这样构建 [Doc]

use itertools::Itertools;
use tiny_pretty::Doc;

fn build_doc(fn_call: &FunctionCall) -> Doc {
    Doc::text(&fn_call.name)
        .append(Doc::text("("))
        .append(
            Doc::line_or_nil()
                .append(Doc::list(Itertools::intersperse(
                    fn_call.args.iter().map(build_doc),
                    Doc::text(",").append(Doc::line_or_space())
                ).collect()))
                .nest(2)
                .append(Doc::line_or_nil())
                .group()
        )
        .append(Doc::text(")"))
}

一旦我们有了 [Doc],我们就可以美化打印它

#
use tiny_pretty::{print, PrintOptions};

assert_eq!(r#"
foo(
  really_long_arg(),
  omg_so_many_parameters(),
  we_should_refactor_this(),
  is_there_seriously_another_one()
)"#.trim(), &print(&build_doc(&fn_call), &PrintOptions::default()));

此外,如果我们有一个足够短,可以放在单行上的函数调用

use tiny_pretty::{print, PrintOptions};

let fn_call = FunctionCall {
    name: "foo".into(),
    args: vec![
        FunctionCall { name: "a".into(), args: vec![] },
        FunctionCall { name: "b".into(), args: vec![] },
        FunctionCall { name: "c".into(), args: vec![] },
        FunctionCall { name: "d".into(), args: vec![] },
    ],
};

#
assert_eq!(
    "foo(a(), b(), c(), d())",
    &print(&build_doc(&fn_call), &PrintOptions::default()),
);

您可以指定高级打印选项,例如控制换行和缩进类型。有关详细信息,请参阅 PrintOptions

文本宽度测量

默认情况下,文本宽度按“视觉宽度”进行测量。这种策略使它满足视觉上的宽度限制。

但是有时对于某些Unicode字符,你可能希望列尽可能接近宽度限制,尽管它将超过视觉上。为了实现这一点,请启用 unicode-width 功能门。

依赖项

~93KB