Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/bash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ impl Bash {
///
pub fn quote_vec<'a, S: ?Sized + Into<Quotable<'a>>>(s: S) -> Vec<u8> {
match s.into() {
Quotable::Byte(byte) => Self::quote_vec(&[byte]),
Quotable::Bytes(bytes) => match bytes::escape_prepare(bytes) {
bytes::Prepared::Empty => vec![b'\'', b'\''],
bytes::Prepared::Inert => bytes.into(),
Expand All @@ -137,6 +138,7 @@ impl Bash {
sout
}
},
Quotable::Char(ch) => Self::quote_vec(&ch.to_string()),
Quotable::Text(text) => match text::escape_prepare(text) {
text::Prepared::Empty => vec![b'\'', b'\''],
text::Prepared::Inert => text.into(),
Expand Down Expand Up @@ -170,6 +172,7 @@ impl Bash {
///
pub fn quote_into_vec<'a, S: ?Sized + Into<Quotable<'a>>>(s: S, sout: &mut Vec<u8>) {
match s.into() {
Quotable::Byte(byte) => Self::quote_into_vec(&[byte], sout),
Quotable::Bytes(bytes) => match bytes::escape_prepare(bytes) {
bytes::Prepared::Empty => sout.extend(b"''"),
bytes::Prepared::Inert => sout.extend(bytes),
Expand All @@ -184,6 +187,7 @@ impl Bash {
debug_assert_eq!(cap, sout.capacity()); // No reallocations.
}
},
Quotable::Char(ch) => Self::quote_into_vec(&ch.to_string(), sout),
Quotable::Text(text) => match text::escape_prepare(text) {
text::Prepared::Empty => sout.extend(b"''"),
text::Prepared::Inert => sout.extend(text.as_bytes()),
Expand Down
4 changes: 4 additions & 0 deletions src/fish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ impl Fish {
/// ```
pub fn quote_vec<'a, S: ?Sized + Into<Quotable<'a>>>(s: S) -> Vec<u8> {
match s.into() {
Quotable::Byte(byte) => Self::quote_vec(&[byte]),
Quotable::Bytes(bytes) => match bytes::escape_prepare(bytes) {
bytes::Prepared::Empty => vec![b'\'', b'\''],
bytes::Prepared::Inert => bytes.into(),
Expand All @@ -99,6 +100,7 @@ impl Fish {
sout
}
},
Quotable::Char(ch) => Self::quote_vec(&ch.to_string()),
Quotable::Text(text) => match text::escape_prepare(text) {
text::Prepared::Empty => vec![b'\'', b'\''],
text::Prepared::Inert => text.into(),
Expand Down Expand Up @@ -128,6 +130,7 @@ impl Fish {
///
pub fn quote_into_vec<'a, S: ?Sized + Into<Quotable<'a>>>(s: S, sout: &mut Vec<u8>) {
match s.into() {
Quotable::Byte(byte) => Self::quote_into_vec(&[byte], sout),
Quotable::Bytes(bytes) => match bytes::escape_prepare(bytes) {
bytes::Prepared::Empty => sout.extend(b"''"),
bytes::Prepared::Inert => sout.extend(bytes),
Expand All @@ -136,6 +139,7 @@ impl Fish {
bytes::escape_chars(esc, sout); // Do the work.
}
},
Quotable::Char(ch) => Self::quote_into_vec(&ch.to_string(), sout),
Quotable::Text(text) => match text::escape_prepare(text) {
text::Prepared::Empty => sout.extend(b"''"),
text::Prepared::Inert => sout.extend(text.as_bytes()),
Expand Down
22 changes: 22 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ where
/// so good. For example, quoting [`OsString`]/[`OsStr`] and
/// [`PathBuf`]/[`Path`] didn't work in a natural way.
pub enum Quotable<'a> {
#[cfg_attr(
not(any(feature = "bash", feature = "fish", feature = "sh")),
allow(unused)
)]
Byte(u8),
#[cfg_attr(
not(any(feature = "bash", feature = "fish", feature = "sh")),
allow(unused)
Expand All @@ -116,9 +121,26 @@ pub enum Quotable<'a> {
not(any(feature = "bash", feature = "fish", feature = "sh")),
allow(unused)
)]
Char(char),
#[cfg_attr(
not(any(feature = "bash", feature = "fish", feature = "sh")),
allow(unused)
)]
Text(&'a str),
}

impl From<u8> for Quotable<'static> {
fn from(source: u8) -> Quotable<'static> {
Quotable::Byte(source)
}
}

impl From<char> for Quotable<'static> {
fn from(source: char) -> Quotable<'static> {
Quotable::Char(source)
}
}

impl<'a> From<&'a [u8]> for Quotable<'a> {
fn from(source: &'a [u8]) -> Quotable<'a> {
Quotable::Bytes(source)
Expand Down
36 changes: 26 additions & 10 deletions src/sh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,21 @@ impl Sh {
/// ```
///
pub fn quote_vec<'a, S: ?Sized + Into<Quotable<'a>>>(s: S) -> Vec<u8> {
let bytes = match s.into() {
Quotable::Bytes(bytes) => bytes,
Quotable::Text(s) => s.as_bytes(),
let quotable = s.into();
let prepared = match quotable {
Quotable::Byte(byte) => escape_prepare(&[byte]),
Quotable::Bytes(bytes) => escape_prepare(bytes),
Quotable::Char(ch) => escape_prepare(ch.to_string().as_bytes()),
Quotable::Text(s) => escape_prepare(s.as_bytes()),
};
match escape_prepare(bytes) {
match prepared {
Prepared::Empty => vec![b'\'', b'\''],
Prepared::Inert => bytes.into(),
Prepared::Inert => match quotable {
Quotable::Byte(byte) => vec![byte],
Quotable::Bytes(bytes) => bytes.to_owned(),
Quotable::Char(ch) => ch.to_string().into(),
Quotable::Text(s) => s.as_bytes().into(),
},
Prepared::Escape(esc) => {
// This may be a pointless optimisation, but calculate the
// memory needed to avoid reallocations as we construct the
Expand Down Expand Up @@ -180,13 +188,21 @@ impl Sh {
/// ```
///
pub fn quote_into_vec<'a, S: ?Sized + Into<Quotable<'a>>>(s: S, sout: &mut Vec<u8>) {
let bytes = match s.into() {
Quotable::Bytes(bytes) => bytes,
Quotable::Text(s) => s.as_bytes(),
let quotable = s.into();
let prepared = match quotable {
Quotable::Byte(byte) => escape_prepare(&[byte]),
Quotable::Bytes(bytes) => escape_prepare(bytes),
Quotable::Char(ch) => escape_prepare(ch.to_string().as_bytes()),
Quotable::Text(s) => escape_prepare(s.as_bytes()),
};
match escape_prepare(bytes) {
match prepared {
Prepared::Empty => sout.extend(b"''"),
Prepared::Inert => sout.extend(bytes),
Prepared::Inert => match quotable {
Quotable::Byte(byte) => sout.push(byte),
Quotable::Bytes(bytes) => sout.extend(bytes),
Quotable::Char(ch) => sout.extend(ch.to_string().as_bytes()),
Quotable::Text(s) => sout.extend(s.as_bytes()),
},
Prepared::Escape(esc) => {
// This may be a pointless optimisation, but calculate the
// memory needed to avoid reallocations as we construct the
Expand Down