#![doc = include_str!("../README.md")]
use std::ffi::{OsStr, OsString};
mod ascii;
mod bash;
mod sh;
pub use bash::Bash;
pub use sh::Sh;
pub trait QuoteExt {
fn push_quoted<Q: Quoter, S: ?Sized + AsRef<[u8]>>(&mut self, q: Q, s: &S);
fn quoted<Q: Quoter, S: ?Sized + AsRef<[u8]>>(q: Q, s: &S) -> Self;
}
impl QuoteExt for Vec<u8> {
fn push_quoted<Q: Quoter, S: ?Sized + AsRef<[u8]>>(&mut self, _q: Q, s: &S) {
Q::quote_into(s, self);
}
fn quoted<Q: Quoter, S: ?Sized + AsRef<[u8]>>(_q: Q, s: &S) -> Self {
Q::quote(s)
}
}
#[cfg(unix)]
impl QuoteExt for OsString {
fn push_quoted<Q: Quoter, S: ?Sized + AsRef<[u8]>>(&mut self, _q: Q, s: &S) {
use std::os::unix::ffi::OsStrExt;
let quoted = Q::quote(s);
self.push(OsStr::from_bytes("ed))
}
fn quoted<Q: Quoter, S: ?Sized + AsRef<[u8]>>(_q: Q, s: &S) -> Self {
use std::os::unix::ffi::OsStringExt;
let quoted = Q::quote(s);
OsString::from_vec(quoted)
}
}
impl QuoteExt for String {
fn push_quoted<Q: Quoter, S: ?Sized + AsRef<[u8]>>(&mut self, _q: Q, s: &S) {
let quoted = Q::quote(s);
let quoted = unsafe { std::str::from_utf8_unchecked("ed) };
self.push_str(quoted);
}
fn quoted<Q: Quoter, S: ?Sized + AsRef<[u8]>>(_q: Q, s: &S) -> Self {
let quoted = Q::quote(s);
unsafe { String::from_utf8_unchecked(quoted) }
}
}
pub(crate) mod quoter {
pub trait QuoterSealed {
fn quote<S: ?Sized + AsRef<[u8]>>(s: &S) -> Vec<u8>;
fn quote_into<S: ?Sized + AsRef<[u8]>>(s: &S, sout: &mut Vec<u8>);
}
}
pub trait Quoter: quoter::QuoterSealed {}