mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 05:15:12 +00:00
Use trait for labels instead of TypeId
(#5270)
This commit is contained in:
parent
1eccbbb60e
commit
3d7411bfaf
2 changed files with 48 additions and 25 deletions
|
@ -528,7 +528,22 @@ impl<Context> Format<Context> for LineSuffixBoundary {
|
||||||
/// use ruff_formatter::prelude::*;
|
/// use ruff_formatter::prelude::*;
|
||||||
/// use ruff_formatter::{format, write, LineWidth};
|
/// use ruff_formatter::{format, write, LineWidth};
|
||||||
///
|
///
|
||||||
/// enum SomeLabelId {}
|
/// #[derive(Debug, Copy, Clone)]
|
||||||
|
/// enum MyLabels {
|
||||||
|
/// Main
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// impl tag::LabelDefinition for MyLabels {
|
||||||
|
/// fn value(&self) -> u64 {
|
||||||
|
/// *self as u64
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn name(&self) -> &'static str {
|
||||||
|
/// match self {
|
||||||
|
/// Self::Main => "Main"
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
///
|
///
|
||||||
/// # fn main() -> FormatResult<()> {
|
/// # fn main() -> FormatResult<()> {
|
||||||
/// let formatted = format!(
|
/// let formatted = format!(
|
||||||
|
@ -537,24 +552,24 @@ impl<Context> Format<Context> for LineSuffixBoundary {
|
||||||
/// let mut recording = f.start_recording();
|
/// let mut recording = f.start_recording();
|
||||||
/// write!(recording, [
|
/// write!(recording, [
|
||||||
/// labelled(
|
/// labelled(
|
||||||
/// LabelId::of::<SomeLabelId>(),
|
/// LabelId::of(MyLabels::Main),
|
||||||
/// &text("'I have a label'")
|
/// &text("'I have a label'")
|
||||||
/// )
|
/// )
|
||||||
/// ])?;
|
/// ])?;
|
||||||
///
|
///
|
||||||
/// let recorded = recording.stop();
|
/// let recorded = recording.stop();
|
||||||
///
|
///
|
||||||
/// let is_labelled = recorded.first().map_or(false, |element| element.has_label(LabelId::of::<SomeLabelId>()));
|
/// let is_labelled = recorded.first().map_or(false, |element| element.has_label(LabelId::of(MyLabels::Main)));
|
||||||
///
|
///
|
||||||
/// if is_labelled {
|
/// if is_labelled {
|
||||||
/// write!(f, [text(" has label SomeLabelId")])
|
/// write!(f, [text(" has label `Main`")])
|
||||||
/// } else {
|
/// } else {
|
||||||
/// write!(f, [text(" doesn't have label SomeLabelId")])
|
/// write!(f, [text(" doesn't have label `Main`")])
|
||||||
/// }
|
/// }
|
||||||
/// })]
|
/// })]
|
||||||
/// )?;
|
/// )?;
|
||||||
///
|
///
|
||||||
/// assert_eq!("'I have a label' has label SomeLabelId", formatted.print()?.as_code());
|
/// assert_eq!("'I have a label' has label `Main`", formatted.print()?.as_code());
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
use crate::format_element::PrintMode;
|
use crate::format_element::PrintMode;
|
||||||
use crate::{GroupId, TextSize};
|
use crate::{GroupId, TextSize};
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
use std::any::type_name;
|
|
||||||
use std::any::TypeId;
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::num::NonZeroU8;
|
use std::num::NonZeroU8;
|
||||||
|
|
||||||
|
@ -235,37 +232,48 @@ impl Align {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Copy, Clone)]
|
#[derive(Debug, Eq, Copy, Clone)]
|
||||||
pub struct LabelId {
|
pub struct LabelId {
|
||||||
id: TypeId,
|
value: u64,
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
label: &'static str,
|
name: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
impl PartialEq for LabelId {
|
||||||
impl std::fmt::Debug for LabelId {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
let is_equal = self.value == other.value;
|
||||||
f.write_str(self.label)
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
|
if is_equal {
|
||||||
|
assert_eq!(self.name, other.name, "Two `LabelId`s with different names have the same `value`. Are you mixing labels of two different `LabelDefinition` or are the values returned by the `LabelDefinition` not unique?");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(debug_assertions))]
|
is_equal
|
||||||
impl std::fmt::Debug for LabelId {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
std::write!(f, "#{:?}", self.id)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LabelId {
|
impl LabelId {
|
||||||
pub fn of<T: ?Sized + 'static>() -> Self {
|
pub fn of<T: LabelDefinition>(label: T) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: TypeId::of::<T>(),
|
value: label.value(),
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
label: type_name::<T>(),
|
name: label.name(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Defines the valid labels of a language. You want to have at most one implementation per formatter
|
||||||
|
/// project.
|
||||||
|
pub trait LabelDefinition {
|
||||||
|
/// Returns the `u64` uniquely identifying this specific label.
|
||||||
|
fn value(&self) -> u64;
|
||||||
|
|
||||||
|
/// Returns the name of the label that is shown in debug builds.
|
||||||
|
fn name(&self) -> &'static str;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
||||||
pub enum VerbatimKind {
|
pub enum VerbatimKind {
|
||||||
Bogus,
|
Bogus,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue