1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//! 函数文档元数据的收集。
//!
//! [`DuckFunctionDocItem`] 由 `#[duck_*]` 属性宏在编译期提交(每个会注册出函数的宏都提交一条,
//! 没写文档参数的三个字段为空),[`declared_function_descriptions`] 把它们按函数名收集合并。
//!
//! 这里**不碰 DuckDB**:不加载扩展、不查 catalog、不做差集。导出成 CSV 是命令行工具的事,
//! 见 `duckfn::cli` 与 `cargo run --bin duckfn -- function_descriptions`。
//!
//! 为什么要绕这一圈:DuckDB 的 C 扩展 API 只暴露了 name / varargs / return_type / volatile /
//! special_handling 这些设置,**没有**设置 description 与 example 的接口,所以这类文本没法随
//! 扩展注册进 catalog。社区扩展的文档页由 `duckdb/community-extensions` 的
//! `scripts/generate_md.sh` 生成,它读扩展目录下的 `docs/function_descriptions.csv`,再按
//! `function_name == other.function` LEFT JOIN 覆盖 `functions` / `functions_overloads` 的展示
//! 列 —— 这份 CSV 是唯一的入口。
//!
//! Collection of the function documentation metadata. [`DuckFunctionDocItem`] is submitted at
//! compile time by the `#[duck_*]` attribute macros (every macro that registers a function submits
//! one; the three fields stay empty when no documentation argument was written) and
//! [`declared_function_descriptions`] merges them by function name. Nothing here touches DuckDB: no
//! extension is loaded, the catalog is never queried and no diff is taken. Turning this into a CSV
//! is the command-line tool's job — see `duckfn::cli` and
//! `cargo run --bin duckfn -- function_descriptions`.
use BTreeMap;
/// 一条函数的文档元数据,由 `#[duck_*]` 宏通过 `inventory::submit!` 提交。
///
/// 字段用 `&'static str` / `&'static [&'static str]` 而不是 `String` / `Vec<String>`:
/// `inventory::submit!` 把值放进 `static` 初始化表达式(const 上下文),堆类型在那里
/// 构造不出来(与 [`crate::DuckScalarOverloadItem`] 的 `name` 同理)。
///
/// One function's documentation metadata, submitted by the `#[duck_*]` macros through
/// `inventory::submit!`. The fields are `&'static str` / `&'static [&'static str]` rather than
/// `String` / `Vec<String>` because `inventory::submit!` places the value in a `static`
/// initialiser (a const context), where heap types cannot be built (same reason as
/// [`crate::DuckScalarOverloadItem`]'s `name`).
// 把 `DuckFunctionDocItem` 登记进 inventory,供 [`declared_function_descriptions`] 遍历。
//
// Collect `DuckFunctionDocItem`s so that [`declared_function_descriptions`] can iterate over them.
collect!;
/// 合并后的函数文档:同一个函数名的多条提交(重载或函数集的各个签名)在这里合成一条。
///
/// A merged function description: several submissions under one function name (overloads, or the
/// signatures of one function set) collapse into a single entry here.
/// 收集源码里声明的全部函数文档,按函数名排序并合并。
///
/// 合并规则:`description` / `comment` 取第一个非空值,`examples` 拼接后按内容去重。
/// 没写文档参数的函数也在结果里(三个字段为空),调用方自行决定要不要过滤
/// ([`FunctionDescription::is_documented`])。
///
/// Collects every function documentation entry declared in the source, sorted by function name and
/// merged. Merging takes the first non-empty `description` / `comment` and concatenates `examples`
/// while dropping duplicates. Functions without any documentation argument are included too (with
/// all three fields empty); filtering them out is up to the caller
/// ([`FunctionDescription::is_documented`]).