diff options
Diffstat (limited to 'core/src/text.rs')
-rw-r--r-- | core/src/text.rs | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/core/src/text.rs b/core/src/text.rs index e437a635..d73eb94a 100644 --- a/core/src/text.rs +++ b/core/src/text.rs @@ -10,6 +10,7 @@ pub use paragraph::Paragraph; use crate::alignment; use crate::{Color, Pixels, Point, Rectangle, Size}; +use std::borrow::Cow; use std::hash::{Hash, Hasher}; /// A paragraph. @@ -220,3 +221,150 @@ pub trait Renderer: crate::Renderer { clip_bounds: Rectangle, ); } + +/// A span of text. +#[derive(Debug, Clone, PartialEq)] +pub struct Span<'a, Font = crate::Font> { + /// The [`Fragment`] of text. + pub text: Fragment<'a>, + /// The size of the [`Span`] in [`Pixels`]. + pub size: Option<Pixels>, + /// The [`LineHeight`] of the [`Span`]. + pub line_height: Option<LineHeight>, + /// The font of the [`Span`]. + pub font: Option<Font>, + /// The [`Color`] of the [`Span`]. + pub color: Option<Color>, +} + +impl<'a, Font> Span<'a, Font> { + /// Creates a new [`Span`] of text with the given text fragment. + pub fn new(fragment: impl IntoFragment<'a>) -> Self { + Self { + text: fragment.into_fragment(), + size: None, + line_height: None, + font: None, + color: None, + } + } + + /// Sets the size of the [`Span`]. + pub fn size(mut self, size: impl Into<Pixels>) -> Self { + self.size = Some(size.into()); + self + } + + /// Sets the [`LineHeight`] of the [`Span`]. + pub fn line_height(mut self, line_height: impl Into<LineHeight>) -> Self { + self.line_height = Some(line_height.into()); + self + } + + /// Sets the font of the [`Span`]. + pub fn font(mut self, font: impl Into<Font>) -> Self { + self.font = Some(font.into()); + self + } + + /// Sets the [`Color`] of the [`Span`]. + pub fn color(mut self, color: impl Into<Color>) -> Self { + self.color = Some(color.into()); + self + } + + /// Turns the [`Span`] into a static one. + pub fn to_static(self) -> Span<'static, Font> { + Span { + text: Cow::Owned(self.text.into_owned()), + size: self.size, + line_height: self.line_height, + font: self.font, + color: self.color, + } + } +} + +impl<'a, Font> From<&'a str> for Span<'a, Font> { + fn from(value: &'a str) -> Self { + Span::new(value) + } +} + +/// A fragment of [`Text`]. +/// +/// This is just an alias to a string that may be either +/// borrowed or owned. +pub type Fragment<'a> = Cow<'a, str>; + +/// A trait for converting a value to some text [`Fragment`]. +pub trait IntoFragment<'a> { + /// Converts the value to some text [`Fragment`]. + fn into_fragment(self) -> Fragment<'a>; +} + +impl<'a> IntoFragment<'a> for Fragment<'a> { + fn into_fragment(self) -> Fragment<'a> { + self + } +} + +impl<'a, 'b> IntoFragment<'a> for &'a Fragment<'b> { + fn into_fragment(self) -> Fragment<'a> { + Fragment::Borrowed(self) + } +} + +impl<'a> IntoFragment<'a> for &'a str { + fn into_fragment(self) -> Fragment<'a> { + Fragment::Borrowed(self) + } +} + +impl<'a> IntoFragment<'a> for &'a String { + fn into_fragment(self) -> Fragment<'a> { + Fragment::Borrowed(self.as_str()) + } +} + +impl<'a> IntoFragment<'a> for String { + fn into_fragment(self) -> Fragment<'a> { + Fragment::Owned(self) + } +} + +macro_rules! into_fragment { + ($type:ty) => { + impl<'a> IntoFragment<'a> for $type { + fn into_fragment(self) -> Fragment<'a> { + Fragment::Owned(self.to_string()) + } + } + + impl<'a> IntoFragment<'a> for &$type { + fn into_fragment(self) -> Fragment<'a> { + Fragment::Owned(self.to_string()) + } + } + }; +} + +into_fragment!(char); +into_fragment!(bool); + +into_fragment!(u8); +into_fragment!(u16); +into_fragment!(u32); +into_fragment!(u64); +into_fragment!(u128); +into_fragment!(usize); + +into_fragment!(i8); +into_fragment!(i16); +into_fragment!(i32); +into_fragment!(i64); +into_fragment!(i128); +into_fragment!(isize); + +into_fragment!(f32); +into_fragment!(f64); |