Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
RiESAEX committed Jul 27, 2024
1 parent a323758 commit 9053abc
Show file tree
Hide file tree
Showing 13 changed files with 130 additions and 115 deletions.
23 changes: 12 additions & 11 deletions crates/biome_cli/src/execute/migrate/eslint_eslint.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use biome_deserialize::Merge;
use biome_deserialize::{
Deserializable, DeserializableValue, DeserializationDiagnostic, DeserializationVisitor,
VisitableType,
Deserializable, DeserializableTypes, DeserializableValue, DeserializationDiagnostic,
DeserializationVisitor, DeserializableType, Merge
};
use biome_deserialize_macros::Deserializable;
use biome_rowan::TextRange;
Expand Down Expand Up @@ -189,7 +188,7 @@ impl Deserializable for GlobalConf {
name: &str,
diagnostics: &mut Vec<biome_deserialize::DeserializationDiagnostic>,
) -> Option<Self> {
if value.visitable_type()? == VisitableType::STR {
if value.visitable_type()? == DeserializableType::Str {
Deserializable::deserialize(value, name, diagnostics).map(Self::Qualifier)
} else {
Deserializable::deserialize(value, name, diagnostics).map(Self::Flag)
Expand Down Expand Up @@ -255,7 +254,7 @@ impl<T: Deserializable> Deserializable for ShorthandVec<T> {
diagnostics: &mut Vec<DeserializationDiagnostic>,
) -> Option<Self> {
Some(ShorthandVec(
if value.visitable_type()? == VisitableType::ARRAY {
if value.visitable_type()? == DeserializableType::Array {
Deserializable::deserialize(value, name, diagnostics)?
} else {
Vec::from_iter([Deserializable::deserialize(value, name, diagnostics)?])
Expand Down Expand Up @@ -316,7 +315,7 @@ impl<T: Deserializable + 'static, U: Deserializable + 'static> Deserializable fo
for Visitor<T, U>
{
type Output = RuleConf<T, U>;
const EXPECTED_TYPE: VisitableType = VisitableType::ARRAY;
const EXPECTED_TYPE: DeserializableTypes = DeserializableTypes::ARRAY;
fn visit_array(
self,
values: impl Iterator<Item = Option<impl DeserializableValue>>,
Expand Down Expand Up @@ -364,8 +363,10 @@ impl<T: Deserializable + 'static, U: Deserializable + 'static> Deserializable fo
Some(RuleConf::Spread(severity, spread))
}
}
let visitable_type = value.visitable_type()?;
if visitable_type == VisitableType::NUMBER || visitable_type == VisitableType::STR {
if matches!(
value.visitable_type()?,
DeserializableType::Number | DeserializableType::Str
) {
Deserializable::deserialize(value, name, diagnostics).map(RuleConf::Severity)
} else {
value.deserialize(Visitor(PhantomData), name, diagnostics)
Expand Down Expand Up @@ -420,7 +421,7 @@ impl Deserializable for NumberOrString {
name: &str,
diagnostics: &mut Vec<biome_deserialize::DeserializationDiagnostic>,
) -> Option<Self> {
Some(if value.visitable_type()? == VisitableType::STR {
Some(if value.visitable_type()? == DeserializableType::Str {
Self::String(Deserializable::deserialize(value, name, diagnostics)?)
} else {
Self::Number(Deserializable::deserialize(value, name, diagnostics)?)
Expand Down Expand Up @@ -456,7 +457,7 @@ impl Deserializable for Rules {
struct Visitor;
impl DeserializationVisitor for Visitor {
type Output = Rules;
const EXPECTED_TYPE: VisitableType = VisitableType::MAP;
const EXPECTED_TYPE: DeserializableTypes = DeserializableTypes::MAP;
fn visit_map(
self,
members: impl Iterator<
Expand Down Expand Up @@ -542,7 +543,7 @@ impl Deserializable for NoRestrictedGlobal {
name: &str,
diagnostics: &mut Vec<DeserializationDiagnostic>,
) -> Option<Self> {
if value.visitable_type()? == VisitableType::STR {
if value.visitable_type()? == DeserializableType::Str {
Deserializable::deserialize(value, name, diagnostics).map(NoRestrictedGlobal::Plain)
} else {
Deserializable::deserialize(value, name, diagnostics)
Expand Down
10 changes: 6 additions & 4 deletions crates/biome_configuration/src/linter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ mod rules;
pub use crate::linter::rules::Rules;
use biome_analyze::options::RuleOptions;
use biome_analyze::{FixKind, RuleFilter};
use biome_deserialize::{Deserializable, StringSet};
use biome_deserialize::{DeserializableValue, DeserializationDiagnostic, Merge, VisitableType};
use biome_deserialize::{
Deserializable, DeserializableType, DeserializableValue, DeserializationDiagnostic, Merge,
StringSet,
};
use biome_deserialize_macros::{Deserializable, Merge, Partial};
use biome_diagnostics::Severity;
use bpaf::Bpaf;
Expand Down Expand Up @@ -80,7 +82,7 @@ impl<T: Default + Deserializable> Deserializable for RuleConfiguration<T> {
rule_name: &str,
diagnostics: &mut Vec<DeserializationDiagnostic>,
) -> Option<Self> {
if value.visitable_type()? == VisitableType::STR {
if value.visitable_type()? == DeserializableType::Str {
Deserializable::deserialize(value, rule_name, diagnostics).map(Self::Plain)
} else {
Deserializable::deserialize(value, rule_name, diagnostics)
Expand Down Expand Up @@ -163,7 +165,7 @@ impl<T: Default + Deserializable> Deserializable for RuleFixConfiguration<T> {
rule_name: &str,
diagnostics: &mut Vec<DeserializationDiagnostic>,
) -> Option<Self> {
if value.visitable_type()? == VisitableType::STR {
if value.visitable_type()? == DeserializableType::Str {
Deserializable::deserialize(value, rule_name, diagnostics).map(Self::Plain)
} else {
Deserializable::deserialize(value, rule_name, diagnostics)
Expand Down
9 changes: 5 additions & 4 deletions crates/biome_configuration/src/parse/json/linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use crate::linter::{RulePlainConfiguration, RuleWithOptions};
use crate::LinterConfiguration;
use crate::RuleConfiguration;
use biome_deserialize::{
Deserializable, DeserializableValue, DeserializationDiagnostic, DeserializationVisitor, Text,
VisitableType,
Deserializable, DeserializableTypes, DeserializableValue, DeserializationDiagnostic,
DeserializationVisitor, Text,
};
use biome_rowan::TextRange;

Expand All @@ -23,7 +23,7 @@ struct LinterConfigurationVisitor;
impl DeserializationVisitor for LinterConfigurationVisitor {
type Output = LinterConfiguration;

const EXPECTED_TYPE: VisitableType = VisitableType::MAP;
const EXPECTED_TYPE: DeserializableTypes = DeserializableTypes::MAP;

fn visit_map(
self,
Expand Down Expand Up @@ -80,7 +80,8 @@ struct RuleConfigurationVisitor<T>(PhantomData<T>);
impl<T: Deserializable + Default> DeserializationVisitor for RuleConfigurationVisitor<T> {
type Output = RuleConfiguration<T>;

const EXPECTED_TYPE: VisitableType = VisitableType::STR.union(VisitableType::MAP);
const EXPECTED_TYPE: DeserializableTypes =
DeserializableTypes::STR.union(DeserializableTypes::MAP);

fn visit_str(
self,
Expand Down
14 changes: 7 additions & 7 deletions crates/biome_deserialize/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ In this case, we'll need to inspect the type of the `DeserializableValue` to kno
to use:

```rust
use biome_deserialize::{DeserializationDiagnostic, Deserializable, DeserializableValue, DeserializationVisitor, Text, VisitableType};
use biome_deserialize::{DeserializationDiagnostic, Deserializable, DeserializableValue, DeserializationVisitor, Text, DeserializableTypes};
use biome_rowan::TextRange;

#[derive(Debug, Eq, PartialEq)]
Expand All @@ -249,7 +249,7 @@ impl Deserializable for Union {
name: &str,
diagnostics: &mut Vec<DeserializationDiagnostic>,
) -> Option<Self> {
if value.is_type(VisitableType::BOOL) {
if value.is_type(DeserializableTypes::BOOL) {
biome_deserialize::Deserializable::deserialize(value, rule_name, diagnostics)
.map(Self::Bool)
} else {
Expand Down Expand Up @@ -286,7 +286,7 @@ methods of the type(s) you expect. Here we expect either a boolean or a string,
`visit_bool()` and `visit_str()`.

We also have to set the associated type `Output` to be a union of the types we expect:
`VisitableType::BOOL.union(VisitableType::STR)`.
`DeserializableTypes::BOOL.union(DeserializableTypes::STR)`.

The full example:

Expand All @@ -307,7 +307,7 @@ impl DeserializationVisitor for UnionVisitor {
type Output = Union;

// We expect a `bool` or a `str` as data type.
const EXPECTED_TYPE: VisitableType = VisitableType::BOOL.union(VisitableType::STR);
const EXPECTED_TYPE: DeserializableTypes = DeserializableTypes::BOOL.union(DeserializableTypes::STR);

// Because we expect a `bool` or a `str`, we have to implement the associated method `visit_bool`.
fn visit_bool(
Expand Down Expand Up @@ -429,7 +429,7 @@ To do that, we create a zero-sized struct `PersonViistor` that implements `Deser
A `DeserializationVisitor` provides several `visit_` methods.
You must implement the `visit_` methods of the type you expect.
Here we expect a map of key-value pairs.
Thus, we implement `visit_map` and set the associated constant `EXPECTED_TYPE` to `VisitableType::MAP`.
Thus, we implement `visit_map` and set the associated constant `EXPECTED_TYPE` to `DeserializableTypes::MAP`.
We also set the associated type `Output` to the type that we want to produce: `Person`.

The implementation of `Deserialziable` for `Person` simply delegates the deserialization of the visitor.
Expand All @@ -449,7 +449,7 @@ Note that if you use _Serde_ in tandem with `biome_deserialize`, you have to dis
Thus, instead of using `String::deserialize` and `u8::deserialize`, you should use `Deserialize::deserialize`.

```rust
use biome_deserialize::{DeserializationDiagnostic, Deserializable, DeserializableValue, DeserializationVisitor, Text, VisitableType};
use biome_deserialize::{DeserializationDiagnostic, Deserializable, DeserializableValue, DeserializationVisitor, Text, DeserializableTypes};
use biome_rowan::TextRange;

#[derive(Debug, Default, Eq, PartialEq, Clone)]
Expand All @@ -473,7 +473,7 @@ impl DeserializationVisitor for PersonVisitor {
type Output = Person;

// We expect a `map` as data type.
const EXPECTED_TYPE: VisitableType = VisitableType::MAP;
const EXPECTED_TYPE: DeserializableTypes = DeserializableTypes::MAP;

// Because we expect a `map`, we have to implement the associated method `visit_map`.
fn visit_map(
Expand Down
71 changes: 40 additions & 31 deletions crates/biome_deserialize/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,41 +11,56 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[bitflags]
#[repr(u8)]
pub(crate) enum Types {
pub enum DeserializableType {
Null = 1 << 0,
Bool = 1 << 1,
Number = 1 << 2,
Str = 1 << 3,
Array = 1 << 4,
Map = 1 << 5,
}
impl std::fmt::Display for DeserializableType {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
fmt,
"{}",
match self {
DeserializableType::Null => "null",
DeserializableType::Bool => "a boolean",
DeserializableType::Number => "a number",
DeserializableType::Str => "a string",
DeserializableType::Array => "an array",
DeserializableType::Map => "an object",
}
)
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct VisitableType(BitFlags<Types>);
impl VisitableType {
pub const NULL: Self = Self(make_bitflags!(Types::{Null}));
pub const BOOL: Self = Self(make_bitflags!(Types::{Bool}));
pub const NUMBER: Self = Self(make_bitflags!(Types::{Number}));
pub const STR: Self = Self(make_bitflags!(Types::{Str}));
pub const ARRAY: Self = Self(make_bitflags!(Types::{Array}));
pub const MAP: Self = Self(make_bitflags!(Types::{Map}));
pub struct DeserializableTypes(BitFlags<DeserializableType>);
impl DeserializableTypes {
pub const NULL: Self = Self(make_bitflags!(DeserializableType::{Null}));
pub const BOOL: Self = Self(make_bitflags!(DeserializableType::{Bool}));
pub const NUMBER: Self = Self(make_bitflags!(DeserializableType::{Number}));
pub const STR: Self = Self(make_bitflags!(DeserializableType::{Str}));
pub const ARRAY: Self = Self(make_bitflags!(DeserializableType::{Array}));
pub const MAP: Self = Self(make_bitflags!(DeserializableType::{Map}));
pub const fn all() -> Self {
Self(BitFlags::ALL)
}
pub const fn empty() -> Self {
Self(BitFlags::EMPTY)
}
pub fn contains(&self, other: impl Into<VisitableType>) -> bool {
pub fn contains(self, other: impl Into<DeserializableTypes>) -> bool {
self.0.contains(other.into().0)
}
pub const fn union(mut self, other: Self) -> Self {
self.0 = self.0.union_c(other.0);
self
pub const fn union(self, other: Self) -> Self {
Self(self.0.union_c(other.0))
}
pub fn is_empty(&self) -> bool {
pub fn is_empty(self) -> bool {
self.0.is_empty()
}
}
impl std::fmt::Display for VisitableType {
impl std::fmt::Display for DeserializableTypes {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
if self.is_empty() {
return write!(fmt, "no value");
Expand All @@ -54,14 +69,6 @@ impl std::fmt::Display for VisitableType {
if i != 0 {
write!(fmt, ", or ")?;
}
let expected_type = match expected_type {
Types::Null => "null",
Types::Bool => "a boolean",
Types::Number => "a number",
Types::Str => "a string",
Types::Array => "an array",
Types::Map => "an object",
};
write!(fmt, "{expected_type}")?;
}
Ok(())
Expand Down Expand Up @@ -98,8 +105,8 @@ impl DeserializationDiagnostic {

/// Emitted when a generic node has an incorrect type
pub fn new_incorrect_type(
actual_type: VisitableType,
expected_type: VisitableType,
actual_type: DeserializableType,
expected_type: DeserializableTypes,
range: impl AsSpan,
) -> Self {
Self::new(markup! {
Expand All @@ -110,8 +117,8 @@ impl DeserializationDiagnostic {

/// Emitted when a generic node has an incorrect type
pub fn new_incorrect_type_with_name(
actual_type: VisitableType,
expected_type: VisitableType,
actual_type: DeserializableType,
expected_type: DeserializableTypes,
name: &str,
range: impl AsSpan,
) -> Self {
Expand Down Expand Up @@ -264,14 +271,16 @@ mod test {

#[test]
fn test_visitable_type_fmt() {
assert_eq!(VisitableType::empty().to_string(), "no value");
assert_eq!(VisitableType::NULL.to_string(), "null");
assert_eq!(DeserializableTypes::empty().to_string(), "no value");
assert_eq!(DeserializableTypes::NULL.to_string(), "null");
assert_eq!(
VisitableType::NULL.union(VisitableType::BOOL).to_string(),
DeserializableTypes::NULL
.union(DeserializableTypes::BOOL)
.to_string(),
"null, or a boolean"
);
assert_eq!(
VisitableType::all().to_string(),
DeserializableTypes::all().to_string(),
"null, or a boolean, or a number, or a string, or an array, or an object"
);
}
Expand Down
Loading

0 comments on commit 9053abc

Please sign in to comment.