Skip to content

Commit

Permalink
refactor(json_deserialize): improve map_to_* API (#616)
Browse files Browse the repository at this point in the history
  • Loading branch information
Conaclos authored Oct 27, 2023
1 parent 55a7aee commit 32fa75c
Show file tree
Hide file tree
Showing 13 changed files with 61 additions and 91 deletions.
34 changes: 11 additions & 23 deletions crates/biome_deserialize/src/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,14 @@ pub trait VisitJsonNode: VisitNode<JsonLanguage> {
/// ## Errors
///
/// The function will emit a generic diagnostic if the `visitor` doesn't implement [visit_member_value]
fn map_to_known_string<T>(
&self,
fn map_to_known_string(
&mut self,
value: &AnyJsonValue,
name: &str,
visitor: &mut T,
diagnostics: &mut Vec<DeserializationDiagnostic>,
) -> Option<()>
where
T: VisitNode<JsonLanguage>,
{
) -> Option<()> {
if JsonStringValue::can_cast(value.syntax().kind()) {
visitor.visit_member_value(value.syntax(), diagnostics)?;
self.visit_member_value(value.syntax(), diagnostics)?;
return Some(());
}
diagnostics.push(DeserializationDiagnostic::new_incorrect_type_for_value(
Expand Down Expand Up @@ -395,16 +391,12 @@ pub trait VisitJsonNode: VisitNode<JsonLanguage> {
/// ## Errors
/// This function will emit diagnostics if:
/// - the `value` can't be cast to [JsonObjectValue]
fn map_to_object<T>(
fn map_to_object(
&mut self,
value: &AnyJsonValue,
name: &str,
visitor: &mut T,
diagnostics: &mut Vec<DeserializationDiagnostic>,
) -> Option<()>
where
T: VisitNode<JsonLanguage>,
{
) -> Option<()> {
let value = JsonObjectValue::cast_ref(value.syntax()).or_else(|| {
diagnostics.push(DeserializationDiagnostic::new_incorrect_type_for_value(
name,
Expand All @@ -415,7 +407,7 @@ pub trait VisitJsonNode: VisitNode<JsonLanguage> {
})?;
for element in value.json_member_list() {
let element = element.ok()?;
visitor.visit_map(
self.visit_map(
element.name().ok()?.syntax(),
element.value().ok()?.syntax(),
diagnostics,
Expand All @@ -424,16 +416,12 @@ pub trait VisitJsonNode: VisitNode<JsonLanguage> {
Some(())
}

fn map_to_array<V>(
&self,
fn map_to_array(
&mut self,
value: &AnyJsonValue,
name: &str,
visitor: &mut V,
diagnostics: &mut Vec<DeserializationDiagnostic>,
) -> Option<()>
where
V: VisitNode<JsonLanguage>,
{
) -> Option<()> {
let array = JsonArrayValue::cast_ref(value.syntax()).or_else(|| {
diagnostics.push(DeserializationDiagnostic::new_incorrect_type_for_value(
name,
Expand All @@ -447,7 +435,7 @@ pub trait VisitJsonNode: VisitNode<JsonLanguage> {
}
for element in array.elements() {
let element = element.ok()?;
visitor.visit_array_member(element.syntax(), diagnostics);
self.visit_array_member(element.syntax(), diagnostics);
}

Some(())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ impl VisitNode<JsonLanguage> for HooksOptions {
for element in array.elements() {
let element = element.ok()?;
let mut hooks = Hooks::default();
self.map_to_object(&element, "hooks", &mut hooks, diagnostics)?;
hooks.map_to_object(&element, "hooks", diagnostics)?;
self.hooks.push(hooks);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -512,9 +512,8 @@ impl VisitNode<JsonLanguage> for NamingConventionOptions {
self.strict_case = self.map_to_boolean(&value, name_text, diagnostics)?
}
"enumMemberCase" => {
let mut enum_member_case = EnumMemberCase::default();
self.map_to_known_string(&value, name_text, &mut enum_member_case, diagnostics)?;
self.enum_member_case = enum_member_case;
self.enum_member_case
.map_to_known_string(&value, name_text, diagnostics)?;
}
_ => (),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,38 +35,38 @@ impl VisitNode<JsonLanguage> for Configuration {
}
"files" => {
let mut files = FilesConfiguration::default();
self.map_to_object(&value, name_text, &mut files, diagnostics)?;
files.map_to_object(&value, name_text, diagnostics)?;
self.files = Some(files);
}
"vcs" => {
let mut vcs = VcsConfiguration::default();
self.map_to_object(&value, name_text, &mut vcs, diagnostics)?;
vcs.map_to_object(&value, name_text, diagnostics)?;
validate_vcs_configuration(&value, &mut vcs, diagnostics);
self.vcs = Some(vcs);
}
"formatter" => {
let mut formatter = FormatterConfiguration::default();
self.map_to_object(&value, name_text, &mut formatter, diagnostics)?;
formatter.map_to_object(&value, name_text, diagnostics)?;
self.formatter = Some(formatter);
}
"linter" => {
let mut linter = LinterConfiguration::default();
self.map_to_object(&value, name_text, &mut linter, diagnostics)?;
linter.map_to_object(&value, name_text, diagnostics)?;
self.linter = Some(linter);
}
"javascript" => {
let mut javascript = JavascriptConfiguration::default();
self.map_to_object(&value, name_text, &mut javascript, diagnostics)?;
javascript.map_to_object(&value, name_text, diagnostics)?;
self.javascript = Some(javascript);
}
"json" => {
let mut json = JsonConfiguration::default();
self.map_to_object(&value, name_text, &mut json, diagnostics)?;
json.map_to_object(&value, name_text, diagnostics)?;
self.json = Some(json);
}
"organizeImports" => {
let mut organize_imports = OrganizeImports::default();
self.map_to_object(&value, name_text, &mut organize_imports, diagnostics)?;
organize_imports.map_to_object(&value, name_text, diagnostics)?;
self.organize_imports = Some(organize_imports);
}
"extends" => {
Expand All @@ -76,7 +76,7 @@ impl VisitNode<JsonLanguage> for Configuration {
}
"overrides" => {
let mut overrides = Overrides::default();
self.map_to_array(&value, name_text, &mut overrides, diagnostics)?;
overrides.map_to_array(&value, name_text, diagnostics)?;
self.overrides = Some(overrides);
}
_ => {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl VisitNode<JsonLanguage> for FormatterConfiguration {

"indentStyle" => {
let mut indent_style = PlainIndentStyle::default();
self.map_to_known_string(&value, name_text, &mut indent_style, diagnostics)?;
indent_style.map_to_known_string(&value, name_text, diagnostics)?;
self.indent_style = Some(indent_style);
}
"indentSize" => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,32 +33,32 @@ impl VisitNode<JsonLanguage> for JavascriptFormatter {
match name_text {
"jsxQuoteStyle" => {
let mut jsx_quote_style = QuoteStyle::default();
self.map_to_known_string(&value, name_text, &mut jsx_quote_style, diagnostics)?;
jsx_quote_style.map_to_known_string(&value, name_text, diagnostics)?;
self.jsx_quote_style = Some(jsx_quote_style);
}
"quoteStyle" => {
let mut quote_style = QuoteStyle::default();
self.map_to_known_string(&value, name_text, &mut quote_style, diagnostics)?;
quote_style.map_to_known_string(&value, name_text, diagnostics)?;
self.quote_style = Some(quote_style);
}
"trailingComma" => {
let mut trailing_comma = TrailingComma::default();
self.map_to_known_string(&value, name_text, &mut trailing_comma, diagnostics)?;
trailing_comma.map_to_known_string(&value, name_text, diagnostics)?;
self.trailing_comma = Some(trailing_comma);
}
"quoteProperties" => {
let mut quote_properties = QuoteProperties::default();
self.map_to_known_string(&value, name_text, &mut quote_properties, diagnostics)?;
quote_properties.map_to_known_string(&value, name_text, diagnostics)?;
self.quote_properties = Some(quote_properties);
}
"semicolons" => {
let mut semicolons = Semicolons::default();
self.map_to_known_string(&value, name_text, &mut semicolons, diagnostics)?;
semicolons.map_to_known_string(&value, name_text, diagnostics)?;
self.semicolons = Some(semicolons);
}
"arrowParentheses" => {
let mut arrow_parentheses = ArrowParentheses::default();
self.map_to_known_string(&value, name_text, &mut arrow_parentheses, diagnostics)?;
arrow_parentheses.map_to_known_string(&value, name_text, diagnostics)?;
self.arrow_parentheses = Some(arrow_parentheses);
}

Expand All @@ -68,7 +68,7 @@ impl VisitNode<JsonLanguage> for JavascriptFormatter {

"indentStyle" => {
let mut indent_style = PlainIndentStyle::default();
self.map_to_known_string(&value, name_text, &mut indent_style, diagnostics)?;
indent_style.map_to_known_string(&value, name_text, diagnostics)?;
self.indent_style = Some(indent_style);
}
"indentSize" => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ impl VisitNode<JsonLanguage> for JavascriptConfiguration {
match name_text {
"formatter" => {
let mut javascript_formatter = JavascriptFormatter::default();
self.map_to_object(&value, name_text, &mut javascript_formatter, diagnostics)?;
javascript_formatter.map_to_object(&value, name_text, diagnostics)?;
self.formatter = Some(javascript_formatter);
}

"parser" => {
let mut parser = JavascriptParser::default();
self.map_to_object(&value, name_text, &mut parser, diagnostics)?;
parser.map_to_object(&value, name_text, diagnostics)?;
self.parser = Some(parser);
}

Expand All @@ -45,12 +45,7 @@ impl VisitNode<JsonLanguage> for JavascriptConfiguration {
}
"organizeImports" => {
let mut javascript_organize_imports = JavascriptOrganizeImports::default();
self.map_to_object(
&value,
name_text,
&mut javascript_organize_imports,
diagnostics,
)?;
javascript_organize_imports.map_to_object(&value, name_text, diagnostics)?;
self.organize_imports = Some(javascript_organize_imports);
}
_ => {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ impl VisitNode<JsonLanguage> for JsonConfiguration {
match name_text {
"parser" => {
let mut parser = JsonParser::default();
self.map_to_object(&value, name_text, &mut parser, diagnostics)?;
parser.map_to_object(&value, name_text, diagnostics)?;
self.parser = Some(parser);
}
"formatter" => {
let mut formatter = JsonFormatter::default();
self.map_to_object(&value, name_text, &mut formatter, diagnostics)?;
formatter.map_to_object(&value, name_text, diagnostics)?;
self.formatter = Some(formatter);
}

Expand Down Expand Up @@ -98,7 +98,7 @@ impl VisitNode<JsonLanguage> for JsonFormatter {

"indentStyle" => {
let mut indent_style = PlainIndentStyle::default();
self.map_to_known_string(&value, name_text, &mut indent_style, diagnostics)?;
indent_style.map_to_known_string(&value, name_text, diagnostics)?;
self.indent_style = Some(indent_style);
}
"indentSize" => {
Expand Down
26 changes: 7 additions & 19 deletions crates/biome_service/src/configuration/parse/json/linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,14 @@ impl VisitNode<JsonLanguage> for LinterConfiguration {
self.enabled = self.map_to_boolean(&value, name_text, diagnostics);
}
"rules" => {
let mut rules = Rules::default();
if are_recommended_and_all_correct(&value, name_text, diagnostics)? {
self.map_to_object(&value, name_text, &mut rules, diagnostics)?;
let mut rules = Rules::default();
rules.map_to_object(&value, name_text, diagnostics)?;
self.rules = Some(rules);
}
}
_ => {}
}

Some(())
}
}
Expand All @@ -62,17 +61,15 @@ impl RuleConfiguration {
) -> Option<()> {
match value {
AnyJsonValue::JsonStringValue(_) => {
let mut configuration = RuleConfiguration::default();
self.map_to_known_string(value, rule_name, &mut configuration, diagnostics)?;
*self = configuration;
self.map_to_known_string(value, rule_name, diagnostics)?;
}
AnyJsonValue::JsonObjectValue(_) => {
let with_options = RuleWithOptions {
level: RulePlainConfiguration::default(),
options: PossibleOptions::new_from_rule_name(rule_name),
};
let mut configuration = RuleConfiguration::WithOptions(with_options);
self.map_to_object(value, rule_name, &mut configuration, diagnostics)?;
configuration.map_to_object(value, rule_name, diagnostics)?;
*self = configuration;
}
_ => {
Expand Down Expand Up @@ -126,17 +123,8 @@ impl VisitNode<JsonLanguage> for RulePlainConfiguration {
diagnostics: &mut Vec<DeserializationDiagnostic>,
) -> Option<()> {
let node = with_only_known_variants(node, RulePlainConfiguration::KNOWN_KEYS, diagnostics)?;
match node.inner_string_text().ok()?.text() {
"error" => {
*self = RulePlainConfiguration::Error;
}
"warn" => {
*self = RulePlainConfiguration::Warn;
}
"off" => {
*self = RulePlainConfiguration::Off;
}
_ => {}
if let Ok(value) = node.inner_string_text().ok()?.text().parse::<Self>() {
*self = value;
}
Some(())
}
Expand Down Expand Up @@ -167,7 +155,7 @@ impl VisitNode<JsonLanguage> for RuleWithOptions {
}
"options" => {
let mut possible_options = self.options.take()?;
self.map_to_object(&value, name_text, &mut possible_options, diagnostics);
possible_options.map_to_object(&value, name_text, diagnostics);
self.options = Some(possible_options);
}
_ => {}
Expand Down
16 changes: 8 additions & 8 deletions crates/biome_service/src/configuration/parse/json/overrides.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl VisitNode<JsonLanguage> for Overrides {
) -> Option<()> {
let mut pattern = OverridePattern::default();
let element = AnyJsonValue::cast_ref(element)?;
self.map_to_object(&element, "overrides", &mut pattern, diagnostics)?;
pattern.map_to_object(&element, "overrides", diagnostics)?;
self.0.push(pattern);
Some(())
}
Expand Down Expand Up @@ -56,27 +56,27 @@ impl VisitNode<JsonLanguage> for OverridePattern {
}
"formatter" => {
let mut formatter = OverrideFormatterConfiguration::default();
self.map_to_object(&value, name_text, &mut formatter, diagnostics)?;
formatter.map_to_object(&value, name_text, diagnostics)?;
self.formatter = Some(formatter);
}
"linter" => {
let mut linter = OverrideLinterConfiguration::default();
self.map_to_object(&value, name_text, &mut linter, diagnostics)?;
linter.map_to_object(&value, name_text, diagnostics)?;
self.linter = Some(linter);
}
"organizeImports" => {
let mut organize_imports = OverrideOrganizeImportsConfiguration::default();
self.map_to_object(&value, name_text, &mut organize_imports, diagnostics)?;
organize_imports.map_to_object(&value, name_text, diagnostics)?;
self.organize_imports = Some(organize_imports);
}
"javascript" => {
let mut javascript = JavascriptConfiguration::default();
self.map_to_object(&value, name_text, &mut javascript, diagnostics)?;
javascript.map_to_object(&value, name_text, diagnostics)?;
self.javascript = Some(javascript);
}
"json" => {
let mut json = JsonConfiguration::default();
self.map_to_object(&value, name_text, &mut json, diagnostics)?;
json.map_to_object(&value, name_text, diagnostics)?;
self.json = Some(json);
}
_ => {}
Expand Down Expand Up @@ -114,7 +114,7 @@ impl VisitNode<JsonLanguage> for OverrideFormatterConfiguration {

"indentStyle" => {
let mut indent_style = PlainIndentStyle::default();
self.map_to_known_string(&value, name_text, &mut indent_style, diagnostics)?;
indent_style.map_to_known_string(&value, name_text, diagnostics)?;
self.indent_style = Some(indent_style);
}
"indentSize" => {
Expand Down Expand Up @@ -179,7 +179,7 @@ impl VisitNode<JsonLanguage> for OverrideLinterConfiguration {
"rules" => {
let mut rules = Rules::default();
if are_recommended_and_all_correct(&value, name_text, diagnostics)? {
self.map_to_object(&value, name_text, &mut rules, diagnostics)?;
rules.map_to_object(&value, name_text, diagnostics)?;
self.rules = Some(rules);
}
}
Expand Down
Loading

0 comments on commit 32fa75c

Please sign in to comment.