thingy/recovered_revisions/src/command_rs/file.331391037786

98 lines
2.7 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use std::fmt;
use std::str::{from_utf8, from_utf8_unchecked};
#[derive(Copy,Clone,Debug,Eq,PartialEq,Ord,PartialOrd)]
pub enum IrcCommand<'a> {
Stringy(Stringy<'a>),
Numeric(Numeric<'a>)
}
#[derive(Copy,Clone,Debug,Eq,PartialEq,Ord,PartialOrd)]
pub struct Stringy<'a>(&'a [u8]);
#[derive(Copy,Clone,Debug,Eq,PartialEq,Ord,PartialOrd)]
pub struct Numeric<'a>(u16, &'a [u8; 3]);
impl<'a> Numeric<'a> {
// not unsafe, but may produce unexpected results
// keep this private
fn new(cmd: &'a [u8; 3]) -> Numeric<'a> {
Numeric(cmd.iter().map(|x| (x-b'0') as u16).fold(0, |x,y| x*10+y), cmd)
}
/// Returns the numeric as a number.
/// # Example
/// ```
/// use uirc::command::IrcCommand;
///
/// if let IrcCommand::Numeric(numeric) = IrcCommand::new(b"005") {
/// match numeric.get_numeric() {
/// 005 => println!("got an ISUPPORT!"),
/// _ => println!("got something else!"),
/// }
/// }
/// ```
pub fn get_numeric(&self) -> u16 {
self.0
}
/// Returns the numeric as bytes.
/// # Example
/// ```rust,ignore
/// use uirc::command::IrcCommand;
///
/// if let IrcCommand::Numeric(numeric) = IrcCommand::new(b"005") {
/// let bytes = numeric.get_bytes();
/// write!(client, bytes);
/// }
/// ```
pub fn get_bytes(&self) -> &'a [u8; 3] {
self.1
}
}
pub trait IrcCommandCall {
fn get_command<'a>(&'a self) -> IrcCommand<'a>;
}
impl<'a> fmt::Display for Stringy<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut i = 0;
let l = self.0.len();
let v = self.0;
while i < l {
let st = from_utf8(&v[i..]);
if let Ok(s) = st {
write!(f, "{}", s)?;
} else {
let err = st.err().unwrap();
write!(f, "{}", unsafe { from_utf8_unchecked(&v[i..][..err.valid_up_to()])})?;
write!(f, "\u{FFFD}")?;
match err.error_len() {
None => i = l,
Some(len) => i = i + err.valid_up_to() + len
}
}
}
Ok(())
}
}
impl<'a> fmt::Display for Numeric<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl<'a> IrcCommand<'a> {
pub fn new(cmd: &'a [u8]) -> IrcCommand<'a> {
if cmd.len() == 3 && matches!((cmd[0], cmd[1], cmd[2]), (b'0'...b'9', b'0'...b'9', b'0'...b'9')) {
// TODO switch to TryFrom/TryInto once those are stable. (rust-lang/rust#33417)
IrcCommand::Numeric(Numeric::new(array_ref![cmd,0,3]))
} else {
IrcCommand::Stringy(Stringy(cmd))
}
}
}