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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// Re-export commonly used types for easier access
pub use ParseError;
use Plan;
use ErrorQueue;
pub use ;
use PlanWriter;
/// Parse a Substrait plan from text format.
///
/// This is the main entry point for parsing well-formed plans.
/// Returns a clear error if parsing fails.
///
/// The input should be in the Substrait text format, which consists of:
/// - An optional extensions section starting with "=== Extensions"
/// - A plan section starting with "=== Plan"
/// - Indented relation definitions
///
/// # Example
/// ```rust
/// use substrait_explain::parse;
///
/// let plan_text = r#"
/// === Plan
/// Root[c, d]
/// Project[$1, 42]
/// Read[schema.table => a:i64, b:string?]
/// "#;
///
/// // Parse the plan. Builds a complete Substrait plan.
/// let plan = parse(plan_text).unwrap();
/// ```
///
/// # Errors
///
/// Returns a `ParseError` if the input cannot be parsed as a valid Substrait plan.
/// The error includes details about what went wrong and where in the input.
///
/// ```rust
/// use substrait_explain::parse;
///
/// let invalid_plan = r#"
/// === Plan
/// InvalidRelation[invalid syntax]
/// "#;
///
/// match parse(invalid_plan) {
/// Ok(_) => println!("Valid plan"),
/// Err(e) => println!("Parse error: {}", e),
/// }
/// ```
/// Parse a Substrait plan from text format with a custom extension registry.
///
/// Use this when the plan contains custom extensions registered via
/// [`extensions::ExtensionRegistry`]. This is the parsing counterpart to
/// [`format_with_registry`].
/// Format a Substrait plan as human-readable text.
///
/// This is the main entry point for formatting plans. It uses default
/// formatting options that produce concise, readable output.
///
/// Returns a tuple of `(formatted_text, errors)`. The text is always generated,
/// even if there are formatting errors. Errors are collected and returned for
/// inspection.
///
/// # Example
/// ```rust
/// use substrait_explain::{parse, format};
/// use substrait::proto::Plan;
///
/// let plan: Plan = parse(r#"
/// === Plan
/// Root[result]
/// Project[$0, $1]
/// Read[data => a:i64, b:string]
/// "#).unwrap();
///
/// let (text, errors) = format(&plan);
/// println!("{}", text);
///
/// if !errors.is_empty() {
/// println!("Formatting warnings: {:?}", errors);
/// }
/// ```
///
/// # Output Format
///
/// The output follows the Substrait text format specification, with relations
/// displayed in a hierarchical structure using indentation.
/// Format a Substrait plan with custom options.
///
/// This function allows you to customize the formatting behavior, such as
/// showing more or less detail, changing indentation, or controlling
/// type visibility.
///
/// # Example
/// ```rust
/// use substrait_explain::{parse, format_with_options, OutputOptions, Visibility};
///
/// let plan = parse(r#"
/// === Plan
/// Root[result]
/// Project[$0, 42]
/// Read[data => a:i64]
/// "#).unwrap();
///
/// // Use verbose formatting
/// let verbose_options = OutputOptions::verbose();
/// let (text, _errors) = format_with_options(&plan, &verbose_options);
/// println!("Verbose output:\n{}", text);
///
/// // Custom options
/// let custom_options = OutputOptions {
/// literal_types: Visibility::Always,
/// indent: " ".to_string(),
/// ..OutputOptions::default()
/// };
/// let (text, _errors) = format_with_options(&plan, &custom_options);
/// println!("Custom output:\n{}", text);
/// ```
///
/// # Options
///
/// See [`OutputOptions`] for all available configuration options.
/// Format a Substrait plan with custom options and an extension registry.
///
/// This function allows you to provide a custom extension registry for handling
/// ExtensionLeaf, ExtensionSingle, and ExtensionMulti relations.
///
/// # Example
/// ```rust,ignore
/// use substrait_explain::{parse, format_with_registry, OutputOptions, ExtensionRegistry};
///
/// let mut registry = ExtensionRegistry::new();
/// // Register custom extensions...
///
/// let plan = parse("...").unwrap();
/// let (text, errors) = format_with_registry(&plan, &OutputOptions::default(), ®istry);
/// ```