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
//! The shell itself: the [`Shell`] type and everything that runs a script, for
//! programs that embed shrub or build a front end on it.
//!
//! `shrub-core` sits between [`shrub_parser`], which turns text into a syntax
//! tree, and the crates that add builtins or a line editor on top. It owns
//! variables, expansion, redirection, jobs, traps, and programmable
//! completion. It has no line editor or prompt drawing of its own.
//!
//! ## Quick start
//!
//! Build a [`Shell`] with [`Shell::builder`], then run text with
//! [`Shell::run_string`]. The shell keeps its variables, functions, and working
//! directory between calls.
//!
//! ```
//! use shrub_core::{Error, Shell, SourceInfo};
//!
//! # #[tokio::main(flavor = "current_thread")]
//! # async fn main() -> Result<(), Error> {
//! let mut shell = Shell::builder().build().await?;
//!
//! let result = shell
//! .run_string(
//! "name=world; greet() { echo \"Hello, $1!\"; }; greet \"$name\"",
//! &SourceInfo::default(),
//! &shell.default_exec_params(),
//! )
//! .await?;
//!
//! assert!(result.is_success());
//! assert_eq!(shell.env_str("name").as_deref(), Some("world"));
//! # Ok::<(), Error>(())
//! # }
//! ```
//!
//! A failed parse or an error the shell cannot continue past comes back as
//! [`Error`]. A command that exits non-zero is not an error: it is an
//! [`ExecutionResult`] whose exit code you inspect.
//!
//! ## Builtins
//!
//! A new shell has no builtins registered. Add them while building, with
//! [`ShellBuilder::builtin`], or later with [`Shell::register_builtin`]. Use
//! [`builtins::builtin`] to register a type that implements
//! [`builtins::Command`], or [`builtins::simple_builtin`] for a
//! [`builtins::SimpleCommand`]. The `shrub-builtins` crate registers the
//! standard set this way.
//!
//! ## Customizing a shell
//!
//! [`Shell`] is generic over [`ShellExtensions`], which swaps in parts of the
//! shell's behavior at compile time; today that is how errors are formatted.
//! Create such a shell with [`Shell::builder_with_extensions`].
//!
//! ## Parsing
//!
//! The syntax tree types are re-exported in [`parser`]. [`Shell::parse_string`]
//! parses with the options the shell currently has set.
//!
//! ## Cargo features
//!
//! | Feature | Effect |
//! |---|---|
//! | `serde` | Implements `Serialize` and `Deserialize` for the syntax tree and other data types, through the same feature of `shrub-parser`. |
//! | `experimental-parser` | Makes the `winnow`-based parser available through [`parser::ParserImpl`], by enabling `shrub-parser`'s `winnow-parser` feature. |
/// Re-export parser types used in core definitions.
pub use ;
pub use ;
pub use ShellExtensions;
pub use ;
pub use ;
pub use ;
pub use ;
pub use SourceInfo;
pub use ;