shrub_core/lib.rs
1//! The shell itself: the [`Shell`] type and everything that runs a script, for
2//! programs that embed shrub or build a front end on it.
3//!
4//! `shrub-core` sits between [`shrub_parser`], which turns text into a syntax
5//! tree, and the crates that add builtins or a line editor on top. It owns
6//! variables, expansion, redirection, jobs, traps, and programmable
7//! completion. It has no line editor or prompt drawing of its own.
8//!
9//! ## Quick start
10//!
11//! Build a [`Shell`] with [`Shell::builder`], then run text with
12//! [`Shell::run_string`]. The shell keeps its variables, functions, and working
13//! directory between calls.
14//!
15//! ```
16//! use shrub_core::{Error, Shell, SourceInfo};
17//!
18//! # #[tokio::main(flavor = "current_thread")]
19//! # async fn main() -> Result<(), Error> {
20//! let mut shell = Shell::builder().build().await?;
21//!
22//! let result = shell
23//! .run_string(
24//! "name=world; greet() { echo \"Hello, $1!\"; }; greet \"$name\"",
25//! &SourceInfo::default(),
26//! &shell.default_exec_params(),
27//! )
28//! .await?;
29//!
30//! assert!(result.is_success());
31//! assert_eq!(shell.env_str("name").as_deref(), Some("world"));
32//! # Ok::<(), Error>(())
33//! # }
34//! ```
35//!
36//! A failed parse or an error the shell cannot continue past comes back as
37//! [`Error`]. A command that exits non-zero is not an error: it is an
38//! [`ExecutionResult`] whose exit code you inspect.
39//!
40//! ## Builtins
41//!
42//! A new shell has no builtins registered. Add them while building, with
43//! [`ShellBuilder::builtin`], or later with [`Shell::register_builtin`]. Use
44//! [`builtins::builtin`] to register a type that implements
45//! [`builtins::Command`], or [`builtins::simple_builtin`] for a
46//! [`builtins::SimpleCommand`]. The `shrub-builtins` crate registers the
47//! standard set this way.
48//!
49//! ## Customizing a shell
50//!
51//! [`Shell`] is generic over [`ShellExtensions`], which swaps in parts of the
52//! shell's behavior at compile time; today that is how errors are formatted.
53//! Create such a shell with [`Shell::builder_with_extensions`].
54//!
55//! ## Parsing
56//!
57//! The syntax tree types are re-exported in [`parser`]. [`Shell::parse_string`]
58//! parses with the options the shell currently has set.
59//!
60//! ## Cargo features
61//!
62//! | Feature | Effect |
63//! |---|---|
64//! | `serde` | Implements `Serialize` and `Deserialize` for the syntax tree and other data types, through the same feature of `shrub-parser`. |
65//! | `experimental-parser` | Makes the `winnow`-based parser available through [`parser::ParserImpl`], by enabling `shrub-parser`'s `winnow-parser` feature. |
66
67#![cfg_attr(docsrs, feature(doc_cfg))]
68
69pub mod arithmetic;
70mod braceexpansion;
71pub mod builtins;
72pub mod callstack;
73pub mod commands;
74pub mod completion;
75pub mod env;
76pub mod error;
77pub mod escape;
78pub mod expansion;
79mod extendedtests;
80pub mod extensions;
81pub mod functions;
82pub mod history;
83pub mod int_utils;
84pub mod interfaces;
85mod interp;
86mod ioutils;
87pub mod jobs;
88mod keywords;
89pub mod namedoptions;
90pub mod openfiles;
91pub mod options;
92pub mod pathcache;
93pub mod pathsearch;
94pub mod patterns;
95pub mod processes;
96mod prompt;
97mod regex;
98pub mod results;
99mod shell;
100pub mod sourceinfo;
101pub mod sys;
102pub mod tasks;
103pub mod terminal;
104pub mod tests;
105pub mod timing;
106pub mod trace_categories;
107pub mod traps;
108pub mod variables;
109mod wellknownvars;
110
111/// Re-export parser types used in core definitions.
112pub mod parser {
113 pub use shrub_parser::{
114 BindingParseError, ParseError, ParserImpl, SourcePosition, SourcePositionOffset,
115 SourceSpan, TestCommandParseError, WordParseError, ast,
116 };
117}
118
119pub use commands::{CommandArg, ExecutionContext};
120pub use error::{BuiltinError, Error, ErrorKind};
121pub use extensions::ShellExtensions;
122pub use interp::{ExecutionParameters, ProcessGroupPolicy};
123pub use parser::{SourcePosition, SourcePositionOffset, SourceSpan};
124pub use results::{ExecutionControlFlow, ExecutionExitCode, ExecutionResult, ExecutionSpawnResult};
125pub use shell::{
126 CreateOptions, ProfileLoadBehavior, RcLoadBehavior, SavedCommandStatus, Shell, ShellBuilder,
127 ShellBuilderState, ShellFd, ShellState,
128};
129pub use sourceinfo::SourceInfo;
130pub use variables::{ShellValue, ShellVariable};