use std::fmt::Debug;
use syntect::{highlighting::Theme, parsing::SyntaxSet};
use crate::{get_cached_syntax_set, get_cached_theme, DocumentStorage, PartialFlexBox,
Size, StyleUSSpanLines};
#[derive(Debug)]
pub struct EditorEngine {
pub current_box: PartialFlexBox,
pub config_options: EditorEngineConfig,
pub syntax_set: &'static SyntaxSet,
pub theme: &'static Theme,
pub parser_byte_cache: Option<ParserByteCache>,
pub ast_cache: Option<StyleUSSpanLines>,
}
pub type ParserByteCache = DocumentStorage;
pub const PARSER_BYTE_CACHE_PAGE_SIZE: usize = 1024;
impl Default for EditorEngine {
fn default() -> Self { EditorEngine::new(EditorEngineConfig::default()) }
}
impl EditorEngine {
#[must_use]
pub fn new(config_options: EditorEngineConfig) -> Self {
Self {
current_box: PartialFlexBox::default(),
config_options,
syntax_set: get_cached_syntax_set(),
theme: get_cached_theme(),
parser_byte_cache: None,
ast_cache: None,
}
}
#[must_use] pub fn viewport(&self) -> Size { self.current_box.style_adjusted_bounds_size }
pub fn set_ast_cache(&mut self, ast_cache: StyleUSSpanLines) {
self.ast_cache = Some(ast_cache);
}
pub fn clear_ast_cache(&mut self) { self.ast_cache = None }
#[must_use] pub fn get_ast_cache(&self) -> Option<&StyleUSSpanLines> { self.ast_cache.as_ref() }
#[must_use] pub fn ast_cache_is_empty(&self) -> bool { self.ast_cache.is_none() }
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct EditorEngineConfig {
pub multiline_mode: LineMode,
pub syntax_highlight: SyntaxHighlightMode,
pub edit_mode: EditMode,
}
mod editor_engine_config_options_impl {
use super::{EditMode, EditorEngineConfig, LineMode, SyntaxHighlightMode};
impl Default for EditorEngineConfig {
fn default() -> Self {
Self {
multiline_mode: LineMode::MultiLine,
syntax_highlight: SyntaxHighlightMode::Enable,
edit_mode: EditMode::ReadWrite,
}
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum EditMode {
ReadOnly,
ReadWrite,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum LineMode {
SingleLine,
MultiLine,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum SyntaxHighlightMode {
Disable,
Enable,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{assert_eq2, height, width};
#[test]
fn test_editor_engine_new() {
let engine = EditorEngine::default();
assert_eq2!(engine.config_options.multiline_mode, LineMode::MultiLine);
assert_eq2!(engine.config_options.syntax_highlight, SyntaxHighlightMode::Enable);
assert_eq2!(engine.config_options.edit_mode, EditMode::ReadWrite);
assert!(engine.parser_byte_cache.is_none());
assert!(engine.ast_cache.is_none());
let custom_config = EditorEngineConfig {
multiline_mode: LineMode::SingleLine,
syntax_highlight: SyntaxHighlightMode::Disable,
edit_mode: EditMode::ReadOnly,
};
let engine = EditorEngine::new(custom_config.clone());
assert_eq2!(engine.config_options, custom_config);
}
#[test]
fn test_viewport() {
let mut engine = EditorEngine::default();
assert_eq2!(engine.viewport(), Size::default());
engine.current_box.style_adjusted_bounds_size = width(100) + height(50);
assert_eq2!(engine.viewport(), width(100) + height(50));
}
#[test]
fn test_ast_cache_operations() {
use crate::List;
let mut engine = EditorEngine::default();
assert!(engine.ast_cache_is_empty());
assert!(engine.get_ast_cache().is_none());
let test_ast: StyleUSSpanLines = List::new();
engine.set_ast_cache(test_ast.clone());
assert!(!engine.ast_cache_is_empty());
assert_eq2!(engine.get_ast_cache(), Some(&test_ast));
engine.clear_ast_cache();
assert!(engine.ast_cache_is_empty());
assert!(engine.get_ast_cache().is_none());
}
#[test]
fn test_editor_engine_config_default() {
let config = EditorEngineConfig::default();
assert_eq2!(config.multiline_mode, LineMode::MultiLine);
assert_eq2!(config.syntax_highlight, SyntaxHighlightMode::Enable);
assert_eq2!(config.edit_mode, EditMode::ReadWrite);
}
#[test]
fn test_config_enums() {
assert_eq2!(EditMode::ReadOnly, EditMode::ReadOnly);
assert_eq2!(EditMode::ReadWrite, EditMode::ReadWrite);
assert!(EditMode::ReadOnly != EditMode::ReadWrite);
assert_eq2!(LineMode::SingleLine, LineMode::SingleLine);
assert_eq2!(LineMode::MultiLine, LineMode::MultiLine);
assert!(LineMode::SingleLine != LineMode::MultiLine);
assert_eq2!(SyntaxHighlightMode::Enable, SyntaxHighlightMode::Enable);
assert_eq2!(SyntaxHighlightMode::Disable, SyntaxHighlightMode::Disable);
assert!(SyntaxHighlightMode::Enable != SyntaxHighlightMode::Disable);
}
#[test]
fn test_parser_byte_cache() {
let mut engine = EditorEngine::default();
assert!(engine.parser_byte_cache.is_none());
engine.parser_byte_cache = Some(DocumentStorage::new());
assert!(engine.parser_byte_cache.is_some());
if let Some(ref mut cache) = engine.parser_byte_cache {
cache.push_str("test content");
assert_eq2!(cache.as_str(), "test content");
}
}
#[test]
fn test_syntax_set_and_theme_are_cached() {
let engine1 = EditorEngine::default();
let engine2 = EditorEngine::default();
assert!(std::ptr::eq(engine1.syntax_set, engine2.syntax_set));
assert!(std::ptr::eq(engine1.theme, engine2.theme));
}
}