Skip to main content

Crate bash_strings

Crate bash_strings 

Source
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.

formwire shapetypewritten 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 what array and rows above 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.
LinkedArr
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.
ParseError
QuotedNest

Enums§

BashVal
Schema

Traits§

BashCodec

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 of parse_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.