14 个版本
0.1.13 | 2023年6月24日 |
---|---|
0.1.12 | 2023年6月21日 |
0.1.11 | 2023年3月28日 |
0.1.8 | 2023年2月21日 |
0.1.7 | 2023年1月31日 |
#369 in 文本处理
3,100 每月下载量
在 5 个crate(2 个直接)中使用
25KB
608 行
特性: phil-wadler 作者
- "ice1000" 开始日期: "2022/12/01"
Wadler 风格的代数精美打印 API 用于 SQL
本 RFC 提出了一种新的 API 用于精美打印伪 "结构"。该 API 的目的是取代当前的 SQL explain 实现,也许更多。
目标
- 使 SQL explain 的输出更“酷”,在意义上使用 ASCII(或 Unicode)艺术来帮助提高输出的可读性。
- 从实现的角度来看,API 应该是可扩展的,并且与实际的 SQL 语法不是紧密耦合的,这样就可以用于其他目的。
- 如果一切顺利,当前的实现将被新的 API 取代。
非目标
- 新的 API 并不是为了性能关键的应用而设计的。SQL explain 并没有被考虑为这样的应用。
- 新的 API 并不旨在像
pretty
crate 那样非常灵活。这给了我们简化和实现设计的机会。
动机
我尝试使用 pretty
crate 来实现 SQL explain,但它被发现有很多局限性
- 标准的 Wadler 风格精美打印 API 只控制行、缩进、文本换行等,这对于复杂的插入框或表格字符的插入不适合。
- 它不支持以任何方式“包装”输出。我们想要在输出周围制作一个大的“盒子”。
- 它不支持制作树形字符,这对于基本操作是必需的,但需要文档到字符串算法中的堆栈。标准
pretty
的实现是一个潜在的配置的纯(Config, Doc) -> String
算法。我相信我们本质上需要将此从读取者单子升级到状态单子。 - 它支持输出水平方向和垂直方向的“挤压”(例如,限制最大列/行数,并通过插入/删除新行来尝试适应),但我们只需要水平挤压。
然而,标准的 Wadler 风格“代数”精美打印 API 设计良好,可以扩展以支持我们所需的功能。我在一个私人 Slack 频道上看到了 @xxchan
的截图,展示了 databend 系统的 SQL explain 输出,这启发了我写这个 RFC。
预期行为
- 用户指定一个首选宽度,通常是终端的宽度,或者80、120等。
- API自动根据首选宽度计算输出的实际宽度。
- 如果所有内容都可以放在一行中,实际宽度就是行的宽度,输出将是一行的。
- 如果输出不能放在一行中,输出将尝试将输出拆分成多行,并尝试将每行的输出拟合到首选宽度。
- API支持用漂亮的ASCII/Unicode艺术包裹输出。
实现
这些内容可能在未来发生变化。
类型
用于美化打印数据的类型 XmlNode
和 Pretty
- 这些枚举是递归定义的,代表可以显示为字符串的对象。
- 美化打印字符串的宽度和高度可以预先计算。
- 枚举
Pretty
的实例此后称为 "美化" 或 "美化者"。 - 结构体
XmlNode
的实例表示具有名称、属性列表和子节点列表的类似XML的数据。
Pretty
的变体
- 变体
Record
,野蛮地美化类似XML的数据。- 它包含一个XML节点。
- 变体
Array
,野蛮地美化类似数组的数据。- 它包含一个美化者的列表。
- 变体
Text
,美化字符串。- 它包含一个写时复制的字符串。
用于美化打印配置的记录 PrettyConfig
它包含缩进、首选宽度等。
用于实际写入字符串的记录 LinedBuffer
它包含一个对 String
的可变引用和一个 PrettyConfig
。它理解预期的宽度(由 PrettyConfig::interesting_*
预先计算),在请求时将尝试用空格填充不完整的行。
重要方法
美化::ol_len_*(&self) -> usize
- 返回美化打印字符串的长度,在一行设置下。
美化::ol_build_string_*(&self,build: &mut String)
- 在一行设置下构建美化打印的字符串。
PrettyConfig::interesting_*
- 预测美化打印字符串的宽度和总长度。
LinedBuffer::line_|
(私有)- 生成一行,不包含起始
|
和结束|
以及缩进。它会尝试填充中间的空格和行,但不是周围的部分。
- 生成一行,不包含起始
PrettyConfig::horizon
- 生成一个指定长度的行,两端是
+
,中间是-
。
- 生成一个指定长度的行,两端是
PrettyConfig::ascii
- 调用
interesting
预测输出宽度,然后使用纯ASCII样式生成漂亮的输出。
- 调用
PrettyConfig::unicode
- 调用
interesting
预测输出宽度,然后使用Unicode表格制作字符生成漂亮的输出。
- 调用
边缘情况
- 所有方法处理空列表和无子记录。无字段记录尚未测试。
更改日志
- 2022年某个时间:添加了Unicode支持
- 2023/01/29:将
BTreeMap
更改为关联向量以保留插入顺序 - 2023/01/31:修复了与美化打印字段相关的错误
- 2023/06/23:添加了对少空格美化打印的支持