### Example: Quote Bytes into Vec - Bash Source: https://docs.rs/shell-quote/0.7.2/src/shell_quote/bash.rs.html Demonstrates how to use `quote_into_vec` to append quoted strings to a buffer. This example shows quoting two strings, one with spaces, and asserts the final buffer content. ```rust let mut buf = Vec::with_capacity(128); Bash::quote_into_vec("foobar", &mut buf); buf.push(b' '); // Add a space. Bash::quote_into_vec("foo bar", &mut buf); assert_eq!(buf, b"foobar $'foo bar'"); ``` -------------------------------- ### Quote Into Vec Example (Sh) Source: https://docs.rs/shell-quote/0.7.2/shell_quote/type.Dash.html Illustrates quoting a string into an existing Vec using Sh. This example appends multiple quoted strings to a buffer, separated by a space. ```rust let mut buf = Vec::with_capacity(128); Sh::quote_into_vec("foobar", &mut buf); buf.push(b' '); // Add a space. Sh::quote_into_vec("foo bar", &mut buf); assert_eq!(buf, b"foobar foo' bar'"); ``` -------------------------------- ### Quote Vec Example (Sh) Source: https://docs.rs/shell-quote/0.7.2/shell_quote/type.Dash.html Demonstrates quoting a string into a new Vec using Sh. It shows how strings without spaces are returned as-is, while strings with spaces are single-quoted. ```rust assert_eq!(Sh::quote_vec("foobar"), b"foobar"); assert_eq!(Sh::quote_vec("foo bar"), b"foo' bar'"); ``` -------------------------------- ### Encoding and Quoting with Different Text Encodings Source: https://docs.rs/shell-quote/0.7.2/shell_quote/index.html Shows how to handle non-UTF-8 text encodings by encoding them first, then quoting. This example uses a hypothetical `encode_iso_8859_1` function to demonstrate quoting ISO-8859-1 data. ```rust let data = "café"; let data_utf8_quoted: Vec = data.quoted(Bash); assert_eq!(&data_utf8_quoted, b"$\'caf\xC3\xA9'"); // UTF-8: 2 bytes for é. // Assuming encode_iso_8859_1 exists and works as described // let data_iso_8859_1: &[u8] = encode_iso_8859_1(data); // let data_iso_8859_1_quoted: Vec = data_iso_8859_1.quoted(Bash); // assert_eq!(&data_iso_8859_1_quoted, b"$\'caf\\xE9'"); // ISO-8859-1: 1 byte, hex escaped. ``` -------------------------------- ### Configure Shell Features in Cargo.toml Source: https://docs.rs/shell-quote/0.7.2/shell_quote/index.html To limit support to specific shells, disable default features and re-enable desired ones in Cargo.toml. This example enables only Bash support. ```toml [dependencies] shell-quote = { version = "*", default-features = false, features = ["bash"] } ``` -------------------------------- ### type_id Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Sh.html Gets the `TypeId` of `self`. ```APIDOC ## fn type_id(&self) -> TypeId ### Description Gets the `TypeId` of `self`. ### Signature `fn type_id(&self) -> TypeId` ``` -------------------------------- ### Basic Quoting for Different Shells Source: https://docs.rs/shell-quote/0.7.2/shell_quote/index.html Demonstrates how to quote simple strings and strings with spaces for various shells using their respective quote_vec functions. Note that Bash and Zsh use $'...' for strings with spaces, while Sh/Dash and Fish use single quotes. ```rust use shell_quote::{Bash, Dash, Fish, Sh, Zsh}; // No quoting is necessary for simple strings. assert_eq!(Sh::quote_vec("foobar"), b"foobar"); assert_eq!(Dash::quote_vec("foobar"), b"foobar"); // `Dash` is an alias for `Sh` assert_eq!(Bash::quote_vec("foobar"), b"foobar"); assert_eq!(Zsh::quote_vec("foobar"), b"foobar"); // `Zsh` is an alias for `Bash` assert_eq!(Fish::quote_vec("foobar"), b"foobar"); // In all shells, quoting is necessary for strings with spaces. assert_eq!(Sh::quote_vec("foo bar"), b"foo' bar'"); assert_eq!(Dash::quote_vec("foo bar"), b"foo' bar'"); assert_eq!(Bash::quote_vec("foo bar"), b"$\'foo bar'"); assert_eq!(Zsh::quote_vec("foo bar"), b"$\'foo bar'"); assert_eq!(Fish::quote_vec("foo bar"), b"foo' bar'"); ``` -------------------------------- ### Get TypeId of self Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Sh.html Retrieves the `TypeId` of the current instance. This is a standard method for trait objects and dynamic type checking. ```rust fn type_id(&self) -> TypeId ``` -------------------------------- ### CloneToUninit Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Bash.html Provides a method to perform copy-assignment from self to a mutable destination pointer. This is an experimental, nightly-only API. ```APIDOC ## unsafe fn clone_to_uninit(&self, dest: *mut u8) ### Description Performs copy-assignment from `self` to `dest`. ### Method `unsafe fn clone_to_uninit` ### Parameters - `dest` (*mut u8) - The mutable pointer to the destination. ### Notes This is a nightly-only experimental API. ``` -------------------------------- ### try_into Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Sh.html Performs the conversion. ```APIDOC ## fn try_into(self) -> Result>::Error> ### Description Performs the conversion. ### Signature `fn try_into(self) -> Result>::Error>` ``` -------------------------------- ### clone_to_uninit Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Sh.html Performs copy-assignment from `self` to `dest`. This is a nightly-only experimental API. ```APIDOC ## unsafe fn clone_to_uninit(&self, dest: *mut u8) ### Description Performs copy-assignment from `self` to `dest`. ### Signature `unsafe fn clone_to_uninit(&self, dest: *mut u8)` ``` -------------------------------- ### Encoding String Data Before Quoting Source: https://docs.rs/shell-quote/0.7.2/shell_quote Demonstrates how to encode string data into a specific encoding (e.g., ISO-8859-1) before quoting it, to ensure correct representation in shells that might not handle UTF-8 directly or as expected. ```rust let data = "café"; let data_utf8_quoted: Vec = data.quoted(Bash); assert_eq!(&data_utf8_quoted, b"$\'caf\xC3\xA9'"); // UTF-8: 2 bytes for é. // Assuming encode_iso_8859_1 is a hypothetical function // let data_iso_8859_1: &[u8] = encode_iso_8859_1(data); // let data_iso_8859_1_quoted: Vec = data_iso_8859_1.quoted(Bash); // assert_eq!(&data_iso_8859_1_quoted, b"$\'caf\\xE9'"); // ISO-8859-1: 1 byte, hex escaped. ``` -------------------------------- ### into Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Sh.html Calls `U::from(self)`. The conversion behavior is determined by the `From for U` implementation. ```APIDOC ## fn into(self) -> U ### Description Calls `U::from(self)`. ### Signature `fn into(self) -> U` ``` -------------------------------- ### Clone into uninitialized memory (Nightly) Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Sh.html Performs copy-assignment from `self` to a raw pointer. This is an experimental, nightly-only API for efficient memory copying. ```rust unsafe fn clone_to_uninit(&self, dest: *mut u8) ``` -------------------------------- ### fn quoted>(self, q: Q) -> Output Source: https://docs.rs/shell-quote/0.7.2/shell_quote/trait.QuoteRefExt.html This is a required method for the QuoteRefExt trait. It takes a Quote implementation and returns the quoted output. ```APIDOC ## fn quoted>(self, q: Q) -> Output ### Description Quotes the input using the provided `Quote` implementation. ### Parameters - **self**: The input to be quoted. - **q**: An instance of a type that implements the `Quote` trait for the desired quoting strategy. ### Returns - **Output**: The quoted representation of the input. ``` -------------------------------- ### Prepare bytes for shell quoting Source: https://docs.rs/shell-quote/0.7.2/src/shell_quote/sh.rs.html The `escape_prepare` function analyzes a byte slice to determine the quoting strategy. It returns `Prepared::Empty` for empty input, `Prepared::Inert` if no special characters are present, or `Prepared::Escape` with a list of characters to be escaped. ```rust fn escape_prepare(sin: &[u8]) -> Prepared { let esc: Vec<_> = sin.iter().map(Char::from).collect(); // An optimisation: if the string is not empty and contains only "safe" // characters we can avoid further work. if esc.is_empty() { Prepared::Empty } else if esc.iter().all(Char::is_inert) { Prepared::Inert } else { Prepared::Escape(esc) } } ``` -------------------------------- ### try_from Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Sh.html Performs the conversion. The `Error` type is `Infallible`. ```APIDOC ## fn try_from(value: U) -> Result>::Error> ### Description Performs the conversion. ### Signature `fn try_from(value: U) -> Result>::Error>` ``` -------------------------------- ### from Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Sh.html Returns the argument unchanged. ```APIDOC ## fn from(t: T) -> T ### Description Returns the argument unchanged. ### Signature `fn from(t: T) -> T` ``` -------------------------------- ### Encoding Differences for Quoting Source: https://docs.rs/shell-quote Shows how different text encodings (UTF-8 vs. ISO-8859-1) affect the quoted output when using `Bash`. This highlights the importance of encoding strings correctly before quoting if a specific encoding is required. ```rust let data = "café"; let data_utf8_quoted: Vec = data.quoted(Bash); assert_eq!(&data_utf8_quoted, b"$\'caf\xC3\xA9'"); // UTF-8: 2 bytes for é. let data_iso_8859_1: &[u8] = encode_iso_8859_1(data); let data_iso_8859_1_quoted: Vec = data_iso_8859_1.quoted(Bash); assert_eq!(&data_iso_8859_1_quoted, b"$\'caf\\xE9'"); // ISO-8859-1: 1 byte, hex escaped. ``` -------------------------------- ### From<&Path> for Quotable Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Implements the From trait for `Path` slices, representing file system paths. This enables quoting of path slices. ```rust impl<'a> From<&'a Path> for Quotable<'a> { fn from(source: &'a Path) -> Quotable<'a> { // ... implementation details ... } } ``` -------------------------------- ### Quote byte strings for /bin/sh Source: https://docs.rs/shell-quote/0.7.2/src/shell_quote/sh.rs.html Implement the `QuoteInto` trait for `Vec` to quote byte strings for /bin/sh. This is the primary method for quoting. ```Rust #![cfg(feature = "sh")] use crate::{ascii::Char, Quotable, QuoteInto}; /// Quote byte strings for use with `/bin/sh`. /// /// # ⚠️ Warning /// /// There is no escape sequence for bytes between 0x80 and 0xFF – these must be /// reproduced exactly in the quoted output – hence **it is not possible to /// safely create or quote into an existing [`String`]** with [`Sh`] because /// these bytes would be misinterpreted as a second or subsequent byte of a /// [multi-byte UTF-8 code point representation][utf-8-encoding]. /// /// [utf-8-encoding]: https://en.wikipedia.org/wiki/UTF-8#Encoding /// /// If you're not using bytes between 0x80 and 0xFF, a workaround is to instead /// quote into a [`Vec`] and convert that into a string using /// [`String::from_utf8`]. The key difference is that `from_utf8` returns a /// [`Result`] which the caller must deal with. /// /// # Compatibility /// /// Quoted/escaped strings produced by [`Sh`] also work in Bash, Dash, and Z /// Shell. /// /// The quoted/escaped strings it produces are different to those coming from /// [`Bash`][`crate::Bash`] or its alias [`Zsh`][`crate::Zsh`]. Those strings /// won't work in a pure `/bin/sh` shell like Dash, but they are better for /// humans to read, to copy and paste. For example, [`Sh`] does not (and cannot) /// escape control characters, but characters like `BEL` and `TAB` (and others) /// are represented by `\a` and `\t` respectively by [`Bash`][`crate::Bash`]. /// /// # Notes /// /// I wasn't able to find any definitive statement of exactly how Bourne Shell /// strings should be quoted, mainly because "Bourne Shell" or `/bin/sh` can /// refer to many different pieces of software: Bash has a Bourne Shell mode, /// `/bin/sh` on Ubuntu is actually Dash, and on macOS 12.3 (and later, and /// possibly earlier) all bets are off: /// /// > `sh` is a POSIX-compliant command interpreter (shell). It is implemented /// > by re-execing as either `bash(1)`, `dash(1)`, or `zsh(1)` as determined by /// > the symbolic link located at `/private/var/select/sh`. If /// > `/private/var/select/sh` does not exist or does not point to a valid /// > shell, `sh` will use one of the supported shells. /// /// However, [dash](https://en.wikipedia.org/wiki/Almquist_shell#dash) appears /// to be the de facto `/bin/sh` these days, having been formally adopted in /// Ubuntu and Debian, and also available as `/bin/dash` on macOS. /// /// From dash(1): /// /// > ## Quoting /// > /// > Quoting is used to remove the special meaning of certain characters or /// > words to the shell, such as operators, whitespace, or keywords. There /// > are three types of quoting: matched single quotes, matched double /// > quotes, and backslash. /// > /// > ## Backslash /// > /// > A backslash preserves the literal meaning of the following character, /// > with the exception of ⟨newline⟩. A backslash preceding a ⟨newline⟩ is /// > treated as a line continuation. /// > /// > ## Single Quotes /// > /// > Enclosing characters in single quotes preserves the literal meaning of /// > all the characters (except single quotes, making it impossible to put /// > single-quotes in a single-quoted string). /// > /// > ## Double Quotes /// > /// > Enclosing characters within double quotes preserves the literal meaning /// > of all characters except dollarsign ($), backquote (`), and backslash /// > (\). The backslash inside double quotes is historically weird, and /// > serves to quote only the following characters: /// > /// > ```text /// > $ ` " . /// > ``` /// > /// > Otherwise it remains literal. /// /// The code in this module operates byte by byte, making no special allowances /// for multi-byte character sets. In other words, it's up to the caller to /// figure out encoding for non-ASCII characters. A significant use case for /// this code is to quote filenames into scripts, and on *nix variants I /// understand that filenames are essentially arrays of bytes, even if the OS /// adds some normalisation and case-insensitivity on top. /// #[derive(Debug, Clone, Copy)] pub struct Sh; impl QuoteInto> for Sh { fn quote_into<'q, S: Into>>(s: S, out: &mut Vec) { Self::quote_into_vec(s, out); } } ``` -------------------------------- ### TryInto for T Trait Implementation Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Shows the `TryInto` trait implementation, which provides a fallible conversion from `Quotable` to other types. It returns a `Result` to handle potential conversion errors. ```rust type Error = >::Error; fn try_into(self) -> Result>::Error> ``` -------------------------------- ### clone_into Method Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Fish.html Uses borrowed data to replace owned data, usually by cloning. This method is useful for efficiently updating existing owned data with new values. ```APIDOC #### fn clone_into(&self, target: &mut T) Uses borrowed data to replace owned data, usually by cloning. Read more Source§ ``` -------------------------------- ### Test u8_to_hex_escape_uppercase_x Function Source: https://docs.rs/shell-quote/0.7.2/src/shell_quote/fish.rs.html Tests the `u8_to_hex_escape_uppercase_x` function by iterating through all possible u8 values and asserting that the generated hex escape sequence matches the expected \\XHH format. ```rust #[test] fn test_u8_to_hex_escape_uppercase_x() { for ch in u8::MIN..=u8::MAX { let expected = format!("\\X{{ch:02X}}"); let observed = u8_to_hex_escape_uppercase_x(ch); let observed = std::str::from_utf8(&observed).unwrap(); assert_eq!(observed, &expected); } } ``` -------------------------------- ### Prepare Bytes for Escaping - Bash Source: https://docs.rs/shell-quote/0.7.2/src/shell_quote/bash.rs.html Prepares a byte slice for Bash-style escaping. It determines if the bytes are empty, inert (safe to use directly), or require escaping. ```rust pub fn escape_prepare(sin: &[u8]) -> Prepared { let esc: Vec<_> = sin.iter().map(Char::from).collect(); // An optimisation: if the string is not empty and contains only "safe" // characters we can avoid further work. if esc.is_empty() { Prepared::Empty } else if esc.iter().all(Char::is_inert) { Prepared::Inert } else { Prepared::Escape(esc) } } ``` -------------------------------- ### Convert Path to Quotable (Unix) Source: https://docs.rs/shell-quote/0.7.2/src/shell_quote/lib.rs.html On Unix systems, implements the `From` trait to convert a `Path` reference into a `Quotable` by first converting it to an `OsStr`. ```rust impl<'a> From<&'a Path> for Quotable<'a> { fn from(source: &'a Path) -> Quotable<'a> { source.as_os_str().into() } } ``` -------------------------------- ### Convert PathBuf to Quotable (Unix) Source: https://docs.rs/shell-quote/0.7.2/src/shell_quote/lib.rs.html On Unix systems, implements the `From` trait to convert a `PathBuf` reference into a `Quotable` by first converting it to an `OsStr`. ```rust impl<'a> From<&'a PathBuf> for Quotable<'a> { fn from(source: &'a PathBuf) -> Quotable<'a> { source.as_os_str().into() } } ``` -------------------------------- ### From<&'a OsString> for Quotable<'a> Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Implementation of the From trait to convert an OsString into a Quotable enum. ```APIDOC ## impl<'a> From<&'a OsString> for Quotable<'a> ### fn from(source: &'a OsString) -> Quotable<'a> Converts to this type from the input type. ``` -------------------------------- ### Zsh Struct Definition Source: https://docs.rs/shell-quote/0.7.2/shell_quote/type.Zsh.html Provides the struct definition for Zsh, which is an alias for Bash. ```rust pub struct Zsh; ``` -------------------------------- ### Quoting with QuoteRefExt Trait Source: https://docs.rs/shell-quote/0.7.2/shell_quote/index.html Shows how to use the `QuoteRefExt` trait for a more concise way to quote strings into different output types (String, Vec) for specified shells. ```rust use shell_quote::{Bash, Sh, Fish, QuoteRefExt}; let quoted: String = "foo bar".quoted(Bash); assert_eq!(quoted, "$\'foo bar'"); let quoted: Vec = "foo bar".quoted(Sh); assert_eq!(quoted, b"foo' bar'"); let quoted: String = "foo bar".quoted(Fish); assert_eq!(quoted, "foo' bar'"); ``` -------------------------------- ### Prepare Byte String for Escaping Source: https://docs.rs/shell-quote/0.7.2/src/shell_quote/fish.rs.html Prepares a byte slice for character escaping. Returns Empty if the slice is empty, Inert if all characters are safe, or Escape with a vector of characters to be escaped. ```rust pub enum Prepared { Empty, Inert, Escape(Vec), } pub fn escape_prepare(sin: &[u8]) -> Prepared { let esc: Vec<_> = sin.iter().map(Char::from).collect(); // An optimisation: if the string is not empty and contains only "safe" // characters we can avoid further work. if esc.is_empty() { Prepared::Empty } else if esc.iter().all(Char::is_inert) { Prepared::Inert } else { Prepared::Escape(esc) } } ``` -------------------------------- ### borrow Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Sh.html Immutably borrows from an owned value. ```APIDOC ## fn borrow(&self) -> &T ### Description Immutably borrows from an owned value. ### Signature `fn borrow(&self) -> &T` ``` -------------------------------- ### QuoteExt Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Bash.html Provides extension methods for quoting, such as `push_quoted`. ```APIDOC ## fn push_quoted<'q, Q, S>(&mut self, _q: Q, s: S) ### Description Appends a quoted string to the current buffer. ### Method `fn push_quoted` ### Parameters - `_q` (Q) - A type that implements `QuoteInto`, used for quoting. - `s` (S) - The string or bytes to be quoted, which can be converted into `Quotable<'q>`. ``` -------------------------------- ### From<&'a Path> for Quotable<'a> Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Implementation of the From trait to convert a Path slice into a Quotable enum. ```APIDOC ## impl<'a> From<&'a Path> for Quotable<'a> ### fn from(source: &'a Path) -> Quotable<'a> Converts to this type from the input type. ``` -------------------------------- ### to_owned Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Sh.html Creates owned data from borrowed data, usually by cloning. ```APIDOC ## fn to_owned(&self) -> T ### Description Creates owned data from borrowed data, usually by cloning. ### Signature `fn to_owned(&self) -> T` ``` -------------------------------- ### From<&'a PathBuf> for Quotable<'a> Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Implementation of the From trait to convert a PathBuf into a Quotable enum. ```APIDOC ## impl<'a> From<&'a PathBuf> for Quotable<'a> ### fn from(source: &'a PathBuf) -> Quotable<'a> Converts to this type from the input type. ``` -------------------------------- ### Into Trait Implementation Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Demonstrates the generic `Into` trait implementation, which leverages the `From` trait implementations. This allows any type that can be converted into Quotable to be converted using `.into()`. ```rust impl Into for T where U: From, { fn into(self) -> U { U::from(self) } } ``` -------------------------------- ### Convert OsString to Quotable (Unix) Source: https://docs.rs/shell-quote/0.7.2/src/shell_quote/lib.rs.html On Unix systems, implements the `From` trait to convert an `OsString` reference into a `Quotable::Bytes` variant by accessing its underlying byte representation. ```rust impl<'a> From<&'a OsString> for Quotable<'a> { fn from(source: &'a OsString) -> Quotable<'a> { use std::os::unix::ffi::OsStrExt; source.as_bytes().into() } } ``` -------------------------------- ### to_owned Method Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Fish.html Creates owned data from borrowed data, typically by cloning. This is a common method for ensuring you have a mutable, owned copy of data. ```APIDOC #### fn to_owned(&self) -> T Creates owned data from borrowed data, usually by cloning. Read more Source§ ``` -------------------------------- ### Prepare Text String for Escaping Source: https://docs.rs/shell-quote/0.7.2/src/shell_quote/fish.rs.html Prepares a string slice for character escaping. Returns Empty if the string is empty, Inert if all characters are safe, or Escape with a vector of characters to be escaped. ```rust pub enum Prepared { Empty, Inert, Escape(Vec), } pub fn escape_prepare(sin: &str) -> Prepared { let esc: Vec<_> = sin.chars().map(Char::from).collect(); // An optimisation: if the string is not empty and contains only "safe" // characters we can avoid further work. if esc.is_empty() { Prepared::Empty } else if esc.iter().all(Char::is_inert) { Prepared::Inert } else { Prepared::Escape(esc) } } ``` -------------------------------- ### Quote byte strings for Fish shell Source: https://docs.rs/shell-quote/0.7.2/src/shell_quote/fish.rs.html Use this function to quote byte strings for use with the Fish shell. It handles necessary escaping to ensure correct interpretation. ```rust #![cfg(feature = "fish")] use crate::{Quotable, QuoteInto}; /// Quote byte strings for use with fish. /// /// # ⚠️ Warning /// /// Prior to version 3.6.2, fish did not correctly handle some Unicode code /// points encoded as UTF-8. From the [version 3.6.2 release notes][]: /// /// > fish uses certain Unicode non-characters internally for marking wildcards /// > and expansions. It incorrectly allowed these markers to be read on command /// > substitution output, rather than transforming them into a safe internal /// > representation. /// /// [version 3.6.2 release notes]: /// https://github.com/fish-shell/fish-shell/releases/tag/3.6.2 /// /// At present this crate has **no workaround** for this issue. Please use fish /// 3.6.2 or later. /// /// # Notes /// /// The documentation on [quoting][] and [escaping characters][] in fish is /// confusing at first, especially when coming from a Bourne-like shell, but /// essentially we have to be able to move and and out of a quoted string /// context. For example, the escape sequence `\t` for a tab _must_ be outside /// of quotes, single or double, to be recognised as a tab character by fish: /// /// ```fish /// echo 'foo'\t'bar' /// ``` /// /// This emphasises the importance of using the correct quoting module for the /// target shell. /// /// [quoting]: https://fishshell.com/docs/current/language.html#quotes /// [escaping characters]: /// https://fishshell.com/docs/current/language.html#escaping-characters #[derive(Debug, Clone, Copy)] pub struct Fish; impl QuoteInto> for Fish { fn quote_into<'q, S: Into>>(s: S, out: &mut Vec) { Self::quote_into_vec(s, out); } } impl QuoteInto for Fish { fn quote_into<'q, S: Into>>(s: S, out: &mut String) { Self::quote_into_vec(s, unsafe { out.as_mut_vec() }) } } #[cfg(unix)] impl QuoteInto for Fish { fn quote_into<'q, S: Into>>(s: S, out: &mut std::ffi::OsString) { use std::os::unix::ffi::OsStringExt; let s = Self::quote_vec(s); let s = std::ffi::OsString::from_vec(s); out.push(s); } } #[cfg(feature = "bstr")] impl QuoteInto for Fish { fn quote_into<'q, S: Into>>(s: S, out: &mut bstr::BString) { let s = Self::quote_vec(s); out.extend(s); } } impl Fish { /// Quote a string of bytes into a new `Vec`. /// /// This will return one of the following: /// - The string as-is, if no escaping is necessary. /// - An escaped string, like `'foo \'bar'`, `\a'ABC'` /// /// See [`quote_into_vec`][`Self::quote_into_vec`] for a variant that /// extends an existing `Vec` instead of allocating a new one. /// /// # Examples /// /// ``` /// # use shell_quote::Fish; /// assert_eq!(Fish::quote_vec("foobar"), b"foobar"); /// assert_eq!(Fish::quote_vec("foo 'bar"), b"foo' \'bar'"); /// ``` pub fn quote_vec<'a, S: Into>>(s: S) -> Vec { match s.into() { Quotable::Bytes(bytes) => match bytes::escape_prepare(bytes) { bytes::Prepared::Empty => vec![b'\'', b'\''], bytes::Prepared::Inert => bytes.into(), bytes::Prepared::Escape(esc) => { let mut sout = Vec::new(); bytes::escape_chars(esc, &mut sout); sout } }, Quotable::Text(text) => match text::escape_prepare(text) { text::Prepared::Empty => vec![b'\'', b'\''], text::Prepared::Inert => text.into(), text::Prepared::Escape(esc) => { let mut sout = Vec::new(); text::escape_chars(esc, &mut sout); sout } }, } } /// Quote a string of bytes into an existing `Vec`. /// /// See [`quote_vec`][`Self::quote_vec`] for more details. /// /// # Examples /// /// ``` /// # use shell_quote::Fish; /// let mut buf = Vec::with_capacity(128); /// Fish::quote_into_vec("foobar", &mut buf); /// buf.push(b' '); // Add a space. /// Fish::quote_into_vec("foo 'bar", &mut buf); /// assert_eq!(buf, b"foobar foo' \'bar'"); /// ``` /// pub fn quote_into_vec<'a, S: Into>>(s: S, sout: &mut Vec) { match s.into() { Quotable::Bytes(bytes) => match bytes::escape_prepare(bytes) { bytes::Prepared::Empty => sout.extend(b"''"), ``` -------------------------------- ### UTF-8 vs. Byte String Quoting with Bash Source: https://docs.rs/shell-quote/0.7.2/shell_quote/index.html Illustrates the difference in quoting behavior between UTF-8 encoded strings and raw byte slices when using Bash. UTF-8 strings are quoted verbatim, while byte slices with non-ASCII characters are hex-escaped. ```rust let data: &str = "café"; let data_utf8_quoted_from_string_type: Vec = data.quoted(Bash); assert_eq!(&data_utf8_quoted_from_string_type, b"$\'caf\xC3\xA9'"); // UTF-8, verbatim. let data_utf8_quoted_from_bytes: Vec = data.as_bytes().quoted(Bash); assert_eq!(&data_utf8_quoted_from_bytes, b"$\'caf\\xC3\\xA9'"); // Now hex escaped! ``` -------------------------------- ### From<&PathBuf> for Quotable Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Implements the From trait for `PathBuf` owned path buffers. This allows conversion of `PathBuf` to Quotable. ```rust impl<'a> From<&'a PathBuf> for Quotable<'a> { fn from(source: &'a PathBuf) -> Quotable<'a> { // ... implementation details ... } } ``` -------------------------------- ### From<&OsStr> for Quotable Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Implements the From trait for `OsStr` slices, which represent operating system-dependent strings. This facilitates quoting of OS strings. ```rust impl<'a> From<&'a OsStr> for Quotable<'a> { fn from(source: &'a OsStr) -> Quotable<'a> { // ... implementation details ... } } ``` -------------------------------- ### TryFrom for T Trait Implementation Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Details the `TryFrom` trait implementation for `Quotable`. This allows for fallible conversions into `Quotable` types, returning a `Result`. ```rust type Error = Infallible; fn try_from(value: U) -> Result>::Error> ``` -------------------------------- ### Implement Char::from for Byte Classification Source: https://docs.rs/shell-quote/0.7.2/src/shell_quote/utf8.rs.html Implements the `from` method for the `Char` enum to convert a `char` into its corresponding `Char` variant. It handles ASCII control characters, printable characters, and UTF-8 sequences, classifying them based on their byte values. ```rust impl Char { pub fn from(ch: char) -> Self { let ascii: Result = ch.try_into(); use Char::*; match ascii { Ok(ascii) => match ascii { // ASCII control characters that frequently have dedicated backslash // sequences when quoted. BEL => Bell, BS => Backspace, ESC => Escape, FF => FormFeed, LF => NewLine, CR => CarriageReturn, TAB => HorizontalTab, VT => VerticalTab, // ASCII control characters, the rest. 0x00..=0x06 | 0x0E..=0x1A | 0x1C..=0x1F => Control(ascii), // ASCII printable characters that can have dedicated backslash // sequences when quoted or otherwise need some special treatment. b'\' => Backslash, b'\'' => SingleQuote, b'"' => DoubleQuote, DEL => Delete, // ASCII printable letters, numbers, and "safe" punctuation. b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' => PrintableInert(ascii), b',' | b'.' | b'/' | b'_' | b'-' => PrintableInert(ascii), // ASCII punctuation which can have significance in the shell. b'|' | b'&' | b';' | b'(' | b')' | b'<' | b'>' => Printable(ascii), b' ' | b'?' | b'[' | b']' | b'{' | b'}' | b'`' => Printable(ascii), b'~' | b'!' | b'$' | b'@' | b'+' | b'=' | b'*' => Printable(ascii), b'%' | b'#' | b':' | b'^' => Printable(ascii), // UTF-8 sequences. 0x80..=0xff => Utf8(ch), }, Err(_) => Utf8(ch), } } #[inline] pub fn is_inert(&self) -> bool { matches!(self, Char::PrintableInert(_)) } } ``` -------------------------------- ### borrow_mut Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Sh.html Mutably borrows from an owned value. ```APIDOC ## fn borrow_mut(&mut self) -> &mut T ### Description Mutably borrows from an owned value. ### Signature `fn borrow_mut(&mut self) -> &mut T` ``` -------------------------------- ### From<&'a String> for Quotable<'a> Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Implementation of the From trait to convert a String into a Quotable enum. ```APIDOC ## impl<'a> From<&'a String> for Quotable<'a> ### fn from(source: &'a String) -> Quotable<'a> Converts to this type from the input type. ``` -------------------------------- ### From<&'a [u8]> for Quotable<'a> Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Implementation of the From trait to convert a byte slice into a Quotable enum. ```APIDOC ## impl<'a> From<&'a [u8]> for Quotable<'a> ### fn from(source: &'a [u8]) -> Quotable<'a> Converts to this type from the input type. ``` -------------------------------- ### Implement QuoteRefExt for generic types Source: https://docs.rs/shell-quote/0.7.2/src/shell_quote/lib.rs.html Provides the `quoted` method for any type that can be converted into `Quotable`. This allows for easy shell quoting of various input types into a default output container. ```rust /// Extension trait for shell quoting many different owned and reference types, /// e.g. `&[u8]`, [`&str`] – anything that's [`Quotable`] – into owned container /// types like [`Vec`], [`String`], [`OsString`] on Unix, and /// [`bstr::BString`] if it's enabled. pub trait QuoteRefExt { fn quoted>(self, q: Q) -> Output; } impl<'a, S, OUT: Default> QuoteRefExt for S where S: Into>, { fn quoted>(self, _q: Q) -> OUT { Q::quote(self) } } ``` -------------------------------- ### From<&OsString> for Quotable Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Implements the From trait for `OsString` owned OS strings. This allows conversion of `OsString` to Quotable. ```rust impl<'a> From<&'a OsString> for Quotable<'a> { fn from(source: &'a OsString) -> Quotable<'a> { // ... implementation details ... } } ``` -------------------------------- ### From<&'a Vec> for Quotable<'a> Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Implementation of the From trait to convert a Vec into a Quotable enum. ```APIDOC ## impl<'a> From<&'a Vec> for Quotable<'a> ### fn from(source: &'a Vec) -> Quotable<'a> Converts to this type from the input type. ``` -------------------------------- ### Quote into OsString on Unix Source: https://docs.rs/shell-quote/0.7.2/src/shell_quote/sh.rs.html Implement the `QuoteInto` trait for `std::ffi::OsString` on Unix systems. This allows direct quoting into OS-specific string types. ```Rust #[cfg(unix)] impl QuoteInto for Sh { fn quote_into<'q, S: Into>>(s: S, out: &mut std::ffi::OsString) { use std::os::unix::ffi::OsStringExt; let s = Self::quote_vec(s); let s = std::ffi::OsString::from_vec(s); out.push(s); } } ``` -------------------------------- ### From<&str> for Quotable Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Implements the From trait for string slices `&str`. This is a common conversion for text data. ```rust impl<'a> From<&'a str> for Quotable<'a> { fn from(source: &'a str) -> Quotable<'a> { // ... implementation details ... } } ``` -------------------------------- ### quote_into for Sh with OsString Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Sh.html Quotes/escapes a string of bytes into an existing OsString container. ```APIDOC ## fn quote_into<'q, S: Into>>(s: S, out: &mut OsString) ### Description Quote/escape a string of bytes into an existing container. ### Signature `fn quote_into<'q, S: Into>>(s: S, out: &mut OsString)` ``` -------------------------------- ### From<&'a BString> for Quotable<'a> Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Implementation of the From trait to convert a BString into a Quotable enum. ```APIDOC ## impl<'a> From<&'a BString> for Quotable<'a> ### fn from(source: &'a BString) -> Quotable<'a> Converts to this type from the input type. ``` -------------------------------- ### From<&BString> for Quotable Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Implements the From trait for `BString` owned byte strings. This enables conversion from `BString` instances. ```rust impl<'a> From<&'a BString> for Quotable<'a> { fn from(source: &'a BString) -> Quotable<'a> { // ... implementation details ... } } ``` -------------------------------- ### Create owned value from value Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Sh.html Returns the argument unchanged, effectively creating an owned value from itself. This is the identity conversion. ```rust fn from(t: T) -> T ``` -------------------------------- ### Create owned data from borrowed data Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Sh.html Creates an owned version of the data, typically by cloning. Use this when you need a distinct copy of borrowed data. ```rust fn to_owned(&self) -> T ``` -------------------------------- ### From<&'a OsStr> for Quotable<'a> Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Implementation of the From trait to convert an OsStr slice into a Quotable enum. ```APIDOC ## impl<'a> From<&'a OsStr> for Quotable<'a> ### fn from(source: &'a OsStr) -> Quotable<'a> Converts to this type from the input type. ``` -------------------------------- ### Sh Struct and QuoteInto Implementations Source: https://docs.rs/shell-quote/0.7.2/src/shell_quote/sh.rs.html The `Sh` struct is used as a type to invoke shell quoting. Implementations of `QuoteInto` allow quoting into `Vec` and `std::ffi::OsString`. ```APIDOC ## struct Sh Represents the quoting strategy for `/bin/sh`. ### `impl QuoteInto> for Sh` Quotes a value into a `Vec` using the `Sh` quoting strategy. #### Method `quote_into<'q, S: Into>>(s: S, out: &mut Vec)` #### Parameters - `s`: The value to quote, which can be any type that implements `Into`. - `out`: A mutable reference to a `Vec` where the quoted output will be appended. ### `impl QuoteInto for Sh` (Unix only) Quotes a value into a `std::ffi::OsString` using the `Sh` quoting strategy. This is only available on Unix-like systems. #### Method `quote_into<'q, S: Into>>(s: S, out: &mut std::ffi::OsString)` #### Parameters - `s`: The value to quote, which can be any type that implements `Into`. - `out`: A mutable reference to an `OsString` where the quoted output will be appended. ### `impl QuoteInto for Sh` (with `bstr` feature) Quotes a value into a `bstr::BString` using the `Sh` quoting strategy. This requires the `bstr` feature to be enabled. ``` -------------------------------- ### Test Char::code() for all bytes Source: https://docs.rs/shell-quote/0.7.2/src/shell_quote/ascii.rs.html This test ensures that the `code()` method correctly returns the original byte value for every possible `u8` input when the `sh` feature is enabled. ```rust #[test] #[cfg(feature = "sh")] fn test_code() { for ch in u8::MIN..=u8::MAX { let char = super::Char::from(ch); assert_eq!(ch, char.code()); } } ``` -------------------------------- ### From<&'a [u8; N]> for Quotable<'a> Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Implementation of the From trait to convert a byte array into a Quotable enum. ```APIDOC ## impl<'a, const N: usize> From<&'a [u8; N]> for Quotable<'a> ### fn from(source: &'a [u8; N]) -> Quotable<'a> Converts to this type from the input type. ``` -------------------------------- ### Convert OsStr to Quotable (Unix) Source: https://docs.rs/shell-quote/0.7.2/src/shell_quote/lib.rs.html On Unix systems, implements the `From` trait to convert an `OsStr` reference into a `Quotable::Bytes` variant by accessing its underlying byte representation. ```rust impl<'a> From<&'a OsStr> for Quotable<'a> { fn from(source: &'a OsStr) -> Quotable<'a> { use std::os::unix::ffi::OsStrExt; source.as_bytes().into() } } ``` -------------------------------- ### From<&Vec> for Quotable Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Implements the From trait for `Vec` byte vectors. This allows conversion from owned byte vectors. ```rust impl<'a> From<&'a Vec> for Quotable<'a> { fn from(source: &'a Vec) -> Quotable<'a> { // ... implementation details ... } } ``` -------------------------------- ### From<&'a str> for Quotable<'a> Source: https://docs.rs/shell-quote/0.7.2/shell_quote/enum.Quotable.html Implementation of the From trait to convert a string slice into a Quotable enum. ```APIDOC ## impl<'a> From<&'a str> for Quotable<'a> ### fn from(source: &'a str) -> Quotable<'a> Converts to this type from the input type. ``` -------------------------------- ### Into for T Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Bash.html Enables conversion from type T into type U, provided that U implements `From`. It calls `U::from(self)`. ```APIDOC ## fn into(self) -> U ### Description Calls `U::from(self)`. This conversion is determined by the `From for U` implementation. ### Method `fn into` ### Parameters - `self` (T) - The value to convert. ``` -------------------------------- ### quote_into for Sh with BString Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Sh.html Quotes/escapes a string of bytes into an existing BString container. ```APIDOC ## fn quote_into<'q, S: Into>>(s: S, out: &mut BString) ### Description Quote/escape a string of bytes into an existing container. ### Signature `fn quote_into<'q, S: Into>>(s: S, out: &mut BString)` ``` -------------------------------- ### Try to convert self into another type Source: https://docs.rs/shell-quote/0.7.2/shell_quote/struct.Sh.html Attempts to convert the current value into another type `U`. This conversion can fail, returning a `Result`. ```rust fn try_into(self) -> Result>::Error> ```