use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub enum RegisterKind {
Charwise,
Linewise,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct Register {
pub text: String,
pub kind: RegisterKind,
}
impl Register {
#[must_use]
pub fn new(text: impl Into<String>, kind: RegisterKind) -> Self {
Self {
text: text.into(),
kind,
}
}
#[must_use]
pub fn charwise(text: impl Into<String>) -> Self {
Self::new(text, RegisterKind::Charwise)
}
#[must_use]
pub fn linewise(text: impl Into<String>) -> Self {
Self::new(text, RegisterKind::Linewise)
}
#[must_use]
pub const fn is_linewise(&self) -> bool {
matches!(self.kind, RegisterKind::Linewise)
}
#[must_use]
pub fn replayed(&self, count: u32) -> String {
let unit = match self.kind {
RegisterKind::Charwise => self.text.clone(),
RegisterKind::Linewise if self.text.ends_with('\n') => self.text.clone(),
RegisterKind::Linewise => {
let mut t = self.text.clone();
t.push('\n');
t
}
};
unit.repeat(count.max(1) as usize)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_linewise_replay_is_newline_terminated_even_when_the_capture_was_not() {
assert_eq!(
Register::linewise("foxtrot").replayed(2),
"foxtrot\nfoxtrot\n"
);
}
#[test]
fn a_charwise_replay_is_verbatim() {
assert_eq!(Register::charwise("ab").replayed(3), "ababab");
}
#[test]
fn a_zero_count_still_puts_once() {
assert_eq!(Register::charwise("x").replayed(0), "x");
}
}