Skip to content

Commit ce7bec0

Browse files
committed
feat(ls): improve the metadata validator by adding a new field regex for string type.
For metadata entries of type `string` the use can now specify a regex that the metadata value must match.
1 parent 17b211f commit ce7bec0

3 files changed

Lines changed: 53 additions & 13 deletions

File tree

ls/src/configuration.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,7 @@ pub struct MetadataValidationRule {
5353
pub ty: Option<String>,
5454
/// Format of the metadata entry, if type is "date".
5555
pub format: Option<String>,
56+
/// Regex pattern to validate the metadata entry, if type is "string".
57+
#[serde(default)]
58+
pub regex: Option<String>,
5659
}

ls/src/features/diagnostics.rs

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ use async_lsp::lsp_types::{
99
use dashmap::mapref::one::Ref;
1010
use serde::{Deserialize, Serialize};
1111

12-
use crate::configuration::MetadataValidationRule;
1312
use chrono::NaiveDate;
13+
use regex::Regex;
1414

15+
use crate::configuration::MetadataValidationRule;
1516
#[cfg(feature = "full-compiler")]
1617
use crate::documents::document::Document;
1718
use crate::documents::storage::DocumentStorage;
@@ -95,18 +96,37 @@ pub fn compiler_diagnostics(
9596
if let Some(ty) = &validation_rule.ty {
9697
match ty.as_str() {
9798
"string" => {
98-
compiler.add_linter(linter.validator(
99-
|meta| {
100-
matches!(
101-
meta.value,
102-
yara_x_parser::ast::MetaValue::String(_)
103-
)
104-
},
105-
format!(
106-
"`{}` must be a `string`",
107-
validation_rule.identifier
108-
),
109-
));
99+
if let Some(pattern) = &validation_rule.regex {
100+
compiler.add_linter(linter.validator(
101+
|meta| {
102+
if let yara_x_parser::ast::MetaValue::String(
103+
value,
104+
) = &meta.value
105+
{
106+
Regex::new(pattern).unwrap().is_match(value.0)
107+
} else {
108+
false
109+
}
110+
},
111+
format!(
112+
"`{}` must be a string and match the pattern `{}`",
113+
validation_rule.identifier, pattern
114+
),
115+
));
116+
} else {
117+
compiler.add_linter(linter.validator(
118+
|meta| {
119+
matches!(
120+
meta.value,
121+
yara_x_parser::ast::MetaValue::String(_)
122+
)
123+
},
124+
format!(
125+
"`{}` must be a `string`",
126+
validation_rule.identifier
127+
),
128+
));
129+
}
110130
}
111131
"integer" => {
112132
compiler.add_linter(linter.validator(

ls/src/server.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,23 @@ impl YARALanguageServer {
704704
),
705705
});
706706
}
707+
708+
for rule in &config.metadata_validation {
709+
if let Some(pattern) = &rule.regex {
710+
if let Err(err) = regex::Regex::new(pattern) {
711+
let _ = client.show_message(ShowMessageParams {
712+
typ: MessageType::ERROR,
713+
message: format!(
714+
"YARA: invalid regex for metadata '{}': {} ({})",
715+
rule.identifier,
716+
pattern,
717+
err
718+
),
719+
});
720+
}
721+
}
722+
}
723+
707724
let _ = client.emit(UpdateConfig(config));
708725
}
709726
None => {

0 commit comments

Comments
 (0)