Expand description
Bash value strings — parse and emit the right-hand side of a bash assignment.
A general utility about bash, standing on its own: nothing here knows about the rig, the wire, or any tool. Three levels, each publicly reachable.
§The shapes bash prints
One call each, no codec and no schema. Every parser is strict, accepting only what bash itself writes; every emitter produces the canonical single-quoted form.
| form | wire shape | type | written in bash by |
|---|---|---|---|
| scalar | 'foo' | String | ${x@Q} |
| q_words | 'a' 'b c' | Vec<String> | ${x[*]@Q} |
| array | ('a' 'b c') | Vec<String> | "(${x[*]@Q})" |
| rows | ("'a' 'b'" "'c'") | Vec<Vec<String>> | one level of nesting |
| indexed | ([0]='a' [5]='b') | IndexMap<usize, String> | ${x[*]@A}, declare -a |
| assoc | (['k']='v') | IndexMap<String, String> | ${x[*]@A}, declare -A |
use bash_strings::{emit_array, parse_array, ParseError};
let words = vec!["compiled".to_string(), "a file.rs".to_string()];
assert_eq!(emit_array(&words), "('compiled' 'a file.rs')");
assert_eq!(parse_array("('compiled' 'a file.rs')")?, words);§Any depth, either encoding
Bash arrays are flat, so a value with structure is encoded textually.
BashVal is one of any depth and Schema is how deep to read it back
— which the text alone does not say. Two BashCodecs flatten one:
-
QuotedNest— each inner array is one bash-literal word at the outer level:[[a,b],[c]]→["('a' 'b')", "('c')"]. The receiver unquotes one layer per level. This is whatarrayandrowsabove use. -
LinkedArr— one flat word stream, each group prefixed by its width:[[a,b],[c]]→[2, a, b, 1, c]. A bash-side walker reads it by taking a width and shifting that many words, with no parser.
use bash_strings::{BashCodec, BashVal, LinkedArr, ParseError, Schema};
let value = BashVal::Arr(vec![BashVal::row(["a", "b"]), BashVal::row(["c"])]);
let text = LinkedArr.emit_literal(&value);
assert_eq!(text, "('2' 'a' 'b' '1' 'c')");
assert_eq!(LinkedArr.parse_literal(&text, &Schema::n_d(2))?, value);Emitting takes the depth from the value and so cannot fail; parsing takes
it from the Schema the caller states.
§A grammar over other syntax
Cursor is the word lexer on its own — bash’s quoting rules with the
stop characters left to the caller — and parse_with runs a grammar over
a whole input. See quoting for a
worked one.
Structs§
- Cursor
- A position in some text, and the bash word grammar over it.
- Linked
Arr - A group is prefixed by its width — the full inner word stream, nested prefixes included — exactly where its elements are themselves groups, since a scalar is already one bash word.
- Parse
Error - Quoted
Nest
Enums§
Traits§
Functions§
- emit_
array - One bash array literal:
["a", "b c"]→('a' 'b c'). The shape a message, an answer and every captured column travel as, and the inverse ofparse_array. - emit_
assoc - emit_
indexed - emit_
q_ words - emit_
scalar - parse_
array - One bash array literal as its words:
('a' 'b c')→["a", "b c"]. - parse_
assoc - parse_
indexed - parse_
scalar - parse_
with - Run a grammar over the whole of
input. Anything it leaves behind is an error, so a grammar cannot quietly match a prefix.