use std::sync::Arc;
use {parking_lot::RwLock, reovim_kernel::api::v1::Service};
#[derive(Debug, Clone)]
pub struct IndentConfig {
language_id: Arc<str>,
tab_size: Option<u32>,
use_tabs: Option<bool>,
}
impl IndentConfig {
#[must_use]
pub fn new(language_id: impl Into<Arc<str>>) -> Self {
Self {
language_id: language_id.into(),
tab_size: None,
use_tabs: None,
}
}
#[must_use]
pub const fn with_tab_size(mut self, size: u32) -> Self {
self.tab_size = Some(size);
self
}
#[must_use]
pub const fn with_use_tabs(mut self, use_tabs: bool) -> Self {
self.use_tabs = Some(use_tabs);
self
}
#[must_use]
pub fn language_id(&self) -> &str {
&self.language_id
}
#[must_use]
pub const fn tab_size(&self) -> Option<u32> {
self.tab_size
}
#[must_use]
pub const fn use_tabs(&self) -> Option<bool> {
self.use_tabs
}
#[must_use]
pub const fn effective_tab_size(&self, fallback: u32) -> u32 {
match self.tab_size {
Some(size) => size,
None => fallback,
}
}
}
#[must_use]
pub fn default_indent_config() -> IndentConfig {
IndentConfig::new("*").with_tab_size(4).with_use_tabs(false)
}
#[derive(Default)]
pub struct IndentConfigStore {
entries: RwLock<Vec<IndentConfig>>,
}
impl IndentConfigStore {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn add(&self, config: IndentConfig) {
self.entries.write().push(config);
}
#[must_use]
pub fn find(&self, language_id: &str) -> Option<IndentConfig> {
self.entries
.read()
.iter()
.find(|c| &*c.language_id == language_id)
.cloned()
}
#[must_use]
pub fn find_or_default(&self, language_id: &str) -> IndentConfig {
self.find(language_id).unwrap_or_else(default_indent_config)
}
#[must_use]
pub fn len(&self) -> usize {
self.entries.read().len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.entries.read().is_empty()
}
}
impl Service for IndentConfigStore {}
impl std::fmt::Debug for IndentConfigStore {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("IndentConfigStore")
.field("count", &self.len())
.finish()
}
}
#[cfg(test)]
#[path = "indent_tests.rs"]
mod tests;