Files
fish-shell/src/builtins/string/unescape.rs
Daniel Rainer 8ae71c80f4 refactor: extract string escape and unescape funcs
Move the functions for escaping and unescaping strings from
`src/common.rs` into `fish_common`. It might make sense to move them
into a dedicated crate at some point, but for now just move them to the
preexisting crate to unblock other extraction.

Closes #12625
2026-04-11 17:49:50 +08:00

58 lines
1.6 KiB
Rust

use super::*;
use fish_common::{UnescapeStringStyle, unescape_string};
#[derive(Default)]
pub struct Unescape {
no_quoted: bool,
style: UnescapeStringStyle,
}
impl StringSubCommand<'_> for Unescape {
const LONG_OPTIONS: &'static [WOption<'static>] = &[
// FIXME: this flag means nothing, but was present in the C++ code
// should be removed
wopt(L!("no-quoted"), NoArgument, 'n'),
wopt(L!("style"), RequiredArgument, NON_OPTION_CHAR),
];
const SHORT_OPTIONS: &'static wstr = L!("n");
fn parse_opt(&mut self, c: char, arg: Option<&wstr>) -> Result<(), StringError<'_>> {
match c {
'n' => self.no_quoted = true,
NON_OPTION_CHAR => {
let arg = arg.unwrap();
self.style = arg
.try_into()
.map_err(|_| err_fmt!("Invalid style value '%s'", arg))?;
}
_ => return Err(StringError::UnknownOption),
}
Ok(())
}
fn handle(
&mut self,
_parser: &Parser,
streams: &mut IoStreams,
optind: &mut usize,
args: &[&wstr],
) -> Result<(), ErrorCode> {
let mut nesc = 0;
for InputValue { arg, want_newline } in arguments(args, optind, streams) {
if let Some(res) = unescape_string(&arg, self.style) {
streams.out.append(&res);
if want_newline {
streams.out.append('\n');
}
nesc += 1;
}
}
if nesc > 0 {
Ok(())
} else {
Err(STATUS_CMD_ERROR)
}
}
}