reovim_kernel/core/option/
spec.rs1use std::borrow::Cow;
4
5use {
6 super::{
7 constraint::OptionConstraint, error::OptionError, scope::OptionScope, value::OptionValue,
8 },
9 crate::api::ModuleId,
10};
11
12#[derive(Debug, Clone)]
28pub struct OptionSpec {
29 pub name: Cow<'static, str>,
31 pub short_form: Option<Cow<'static, str>>,
33 pub description: Cow<'static, str>,
35 pub default: OptionValue,
37 pub constraint: OptionConstraint,
39 pub scope: OptionScope,
41 pub owner: Option<ModuleId>,
43}
44
45impl OptionSpec {
46 #[must_use]
48 pub fn new(
49 name: impl Into<Cow<'static, str>>,
50 description: impl Into<Cow<'static, str>>,
51 default: OptionValue,
52 ) -> Self {
53 Self {
54 name: name.into(),
55 description: description.into(),
56 default,
57 short_form: None,
58 constraint: OptionConstraint::none(),
59 scope: OptionScope::default(),
60 owner: None,
61 }
62 }
63
64 #[must_use]
66 pub fn with_short(mut self, short: impl Into<Cow<'static, str>>) -> Self {
67 self.short_form = Some(short.into());
68 self
69 }
70
71 #[must_use]
73 pub const fn with_constraint(mut self, constraint: OptionConstraint) -> Self {
74 self.constraint = constraint;
75 self
76 }
77
78 #[must_use]
80 pub const fn with_scope(mut self, scope: OptionScope) -> Self {
81 self.scope = scope;
82 self
83 }
84
85 #[must_use]
87 pub fn with_owner(mut self, owner: ModuleId) -> Self {
88 self.owner = Some(owner);
89 self
90 }
91
92 #[must_use]
94 pub const fn owner(&self) -> Option<&ModuleId> {
95 self.owner.as_ref()
96 }
97
98 #[must_use]
100 pub fn matches_name(&self, query: &str) -> bool {
101 self.name == query
102 || self
103 .short_form
104 .as_ref()
105 .is_some_and(|s: &Cow<'static, str>| s.as_ref() == query)
106 }
107
108 pub fn validate(&self, value: &OptionValue) -> Result<(), OptionError> {
114 if !self.default.same_type(value) {
116 return Err(OptionError::TypeMismatch {
117 name: self.name.to_string(),
118 expected: self.default.type_name(),
119 got: value.type_name(),
120 });
121 }
122
123 self.constraint
125 .validate(value)
126 .map_err(|e| OptionError::ValidationFailed {
127 name: self.name.to_string(),
128 reason: e.to_string(),
129 })
130 }
131}