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
14 changes: 7 additions & 7 deletions src/bash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,9 @@ impl Bash {
///
pub fn quote_vec<'a, S: ?Sized + Into<Quotable<'a>>>(s: S) -> Vec<u8> {
match s.into() {
Quotable::Bytes(bytes) => match bytes::escape_prepare(bytes) {
Quotable::Bytes(ref bytes) => match bytes::escape_prepare(bytes) {
bytes::Prepared::Empty => vec![b'\'', b'\''],
bytes::Prepared::Inert => bytes.into(),
bytes::Prepared::Inert => bytes.clone().into_owned(),
bytes::Prepared::Escape(esc) => {
// This may be a pointless optimisation, but calculate the
// memory needed to avoid reallocations as we construct the
Expand All @@ -137,9 +137,9 @@ impl Bash {
sout
}
},
Quotable::Text(text) => match text::escape_prepare(text) {
Quotable::Text(ref text) => match text::escape_prepare(text) {
text::Prepared::Empty => vec![b'\'', b'\''],
text::Prepared::Inert => text.into(),
text::Prepared::Inert => text.as_bytes().into(),
text::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 @@ -170,9 +170,9 @@ impl Bash {
///
pub fn quote_into_vec<'a, S: ?Sized + Into<Quotable<'a>>>(s: S, sout: &mut Vec<u8>) {
match s.into() {
Quotable::Bytes(bytes) => match bytes::escape_prepare(bytes) {
Quotable::Bytes(ref bytes) => match bytes::escape_prepare(bytes) {
bytes::Prepared::Empty => sout.extend(b"''"),
bytes::Prepared::Inert => sout.extend(bytes),
bytes::Prepared::Inert => sout.extend(bytes.as_ref()),
bytes::Prepared::Escape(esc) => {
// This may be a pointless optimisation, but calculate the
// memory needed to avoid reallocations as we construct the
Expand All @@ -184,7 +184,7 @@ impl Bash {
debug_assert_eq!(cap, sout.capacity()); // No reallocations.
}
},
Quotable::Text(text) => match text::escape_prepare(text) {
Quotable::Text(ref text) => match text::escape_prepare(text) {
text::Prepared::Empty => sout.extend(b"''"),
text::Prepared::Inert => sout.extend(text.as_bytes()),
text::Prepared::Escape(esc) => {
Expand Down
14 changes: 7 additions & 7 deletions src/fish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,18 @@ impl Fish {
/// ```
pub fn quote_vec<'a, S: ?Sized + Into<Quotable<'a>>>(s: S) -> Vec<u8> {
match s.into() {
Quotable::Bytes(bytes) => match bytes::escape_prepare(bytes) {
Quotable::Bytes(ref bytes) => match bytes::escape_prepare(bytes) {
bytes::Prepared::Empty => vec![b'\'', b'\''],
bytes::Prepared::Inert => bytes.into(),
bytes::Prepared::Inert => bytes.clone().into_owned(),
bytes::Prepared::Escape(esc) => {
let mut sout = Vec::with_capacity(esc.len() + 2);
bytes::escape_chars(esc, &mut sout); // Do the work.
sout
}
},
Quotable::Text(text) => match text::escape_prepare(text) {
Quotable::Text(ref text) => match text::escape_prepare(text) {
text::Prepared::Empty => vec![b'\'', b'\''],
text::Prepared::Inert => text.into(),
text::Prepared::Inert => text.as_bytes().into(),
text::Prepared::Escape(esc) => {
let mut sout = Vec::with_capacity(esc.len() + 2);
text::escape_chars(esc, &mut sout); // Do the work.
Expand All @@ -128,15 +128,15 @@ impl Fish {
///
pub fn quote_into_vec<'a, S: ?Sized + Into<Quotable<'a>>>(s: S, sout: &mut Vec<u8>) {
match s.into() {
Quotable::Bytes(bytes) => match bytes::escape_prepare(bytes) {
Quotable::Bytes(ref bytes) => match bytes::escape_prepare(bytes) {
bytes::Prepared::Empty => sout.extend(b"''"),
bytes::Prepared::Inert => sout.extend(bytes),
bytes::Prepared::Inert => sout.extend(bytes.as_ref()),
bytes::Prepared::Escape(esc) => {
sout.reserve(esc.len() + 2);
bytes::escape_chars(esc, sout); // Do the work.
}
},
Quotable::Text(text) => match text::escape_prepare(text) {
Quotable::Text(ref text) => match text::escape_prepare(text) {
text::Prepared::Empty => sout.extend(b"''"),
text::Prepared::Inert => sout.extend(text.as_bytes()),
text::Prepared::Escape(esc) => {
Expand Down
27 changes: 20 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
doc = include_str!("../README.md")
)]

use std::borrow::Cow;
use std::ffi::{OsStr, OsString};
use std::path::{Path, PathBuf};

Expand Down Expand Up @@ -111,41 +112,53 @@ pub enum Quotable<'a> {
not(any(feature = "bash", feature = "fish", feature = "sh")),
allow(unused)
)]
Bytes(&'a [u8]),
Bytes(Cow<'a, [u8]>),
#[cfg_attr(
not(any(feature = "bash", feature = "fish", feature = "sh")),
allow(unused)
)]
Text(&'a str),
Text(Cow<'a, str>),
}

impl From<u8> for Quotable<'static> {
fn from(source: u8) -> Quotable<'static> {
Quotable::Bytes(Cow::Owned(vec![source]))
}
}

impl From<char> for Quotable<'static> {
fn from(source: char) -> Quotable<'static> {
Quotable::Text(Cow::Owned(source.to_string()))
}
}

impl<'a> From<&'a [u8]> for Quotable<'a> {
fn from(source: &'a [u8]) -> Quotable<'a> {
Quotable::Bytes(source)
Quotable::Bytes(Cow::Borrowed(source))
}
}

impl<'a, const N: usize> From<&'a [u8; N]> for Quotable<'a> {
fn from(source: &'a [u8; N]) -> Quotable<'a> {
Quotable::Bytes(&source[..])
Quotable::Bytes(Cow::Borrowed(&source[..]))
}
}

impl<'a> From<&'a Vec<u8>> for Quotable<'a> {
fn from(source: &'a Vec<u8>) -> Quotable<'a> {
Quotable::Bytes(source)
Quotable::Bytes(Cow::Borrowed(source))
}
}

impl<'a> From<&'a str> for Quotable<'a> {
fn from(source: &'a str) -> Quotable<'a> {
Quotable::Text(source)
Quotable::Text(Cow::Borrowed(source))
}
}

impl<'a> From<&'a String> for Quotable<'a> {
fn from(source: &'a String) -> Quotable<'a> {
Quotable::Text(source)
Quotable::Text(Cow::Borrowed(source))
}
}

Expand Down
14 changes: 8 additions & 6 deletions src/sh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,10 @@ 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 bytes = match quotable {
Quotable::Bytes(ref bytes) => bytes.as_ref(),
Quotable::Text(ref text) => text.as_bytes(),
};
match escape_prepare(bytes) {
Prepared::Empty => vec![b'\'', b'\''],
Expand Down Expand Up @@ -180,9 +181,10 @@ 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 bytes = match quotable {
Quotable::Bytes(ref bytes) => bytes.as_ref(),
Quotable::Text(ref text) => text.as_bytes(),
};
match escape_prepare(bytes) {
Prepared::Empty => sout.extend(b"''"),
Expand Down