use bevy::prelude::Resource;
use std::fmt::{Display, Formatter};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum VimError {
NoFileName,
NoPreviousRegularExpression,
NoWriteSinceLastChange,
CantOpenFileForWriting,
PatternNotFound,
NotAnEditorCommand,
}
impl VimError {
#[must_use]
pub const fn code(self) -> &'static str {
match self {
Self::NoFileName => "E32",
Self::NoPreviousRegularExpression => "E35",
Self::NoWriteSinceLastChange => "E37",
Self::CantOpenFileForWriting => "E212",
Self::PatternNotFound => "E486",
Self::NotAnEditorCommand => "E492",
}
}
#[must_use]
pub const fn message(self) -> &'static str {
match self {
Self::NoFileName => "No file name",
Self::NoPreviousRegularExpression => "No previous regular expression",
Self::NoWriteSinceLastChange => "No write since last change",
Self::CantOpenFileForWriting => "Can't open file for writing",
Self::PatternNotFound => "Pattern not found",
Self::NotAnEditorCommand => "Not an editor command",
}
}
#[must_use]
pub fn status_text(self) -> String {
format!("{}: {}", self.code(), self.message())
}
}
impl Display for VimError {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
formatter.write_str(&self.status_text())
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum VimStatusMessage {
Error(VimError),
Info(String),
}
impl VimStatusMessage {
#[must_use]
pub fn text(self) -> String {
match self {
Self::Error(error) => error.status_text(),
Self::Info(text) => text,
}
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq, Resource)]
pub struct VimStatusLine {
message: Option<VimStatusMessage>,
}
impl VimStatusLine {
pub fn clear(&mut self) {
self.message = None;
}
pub fn set_error(&mut self, error: VimError) {
self.message = Some(VimStatusMessage::Error(error));
}
pub fn set_info(&mut self, text: impl Into<String>) {
self.message = Some(VimStatusMessage::Info(text.into()));
}
#[must_use]
pub const fn message(&self) -> Option<&VimStatusMessage> {
self.message.as_ref()
}
}
#[cfg(test)]
mod tests {
use super::{VimError, VimStatusLine, VimStatusMessage};
#[test]
fn vim_errors_render_with_codes() {
assert_eq!(
VimError::PatternNotFound.status_text(),
"E486: Pattern not found"
);
assert_eq!(VimError::NoFileName.status_text(), "E32: No file name");
assert_eq!(
VimError::NoPreviousRegularExpression.status_text(),
"E35: No previous regular expression"
);
}
#[test]
fn status_line_tracks_errors_and_clear() {
let mut status_line = VimStatusLine::default();
status_line.set_error(VimError::PatternNotFound);
assert_eq!(
status_line.message(),
Some(&VimStatusMessage::Error(VimError::PatternNotFound))
);
status_line.clear();
assert_eq!(status_line.message(), None);
status_line.set_info("written");
assert_eq!(
status_line.message(),
Some(&VimStatusMessage::Info(String::from("written")))
);
}
}