1use crate::point::Point;
9use crate::rect::Rect;
10use crate::traits::*;
11use num_traits::NumCast;
12use std::fmt;
13use std::hash::Hash;
14use std::ops::Deref;
15
16pub trait TextType: Eq + Hash + Clone + fmt::Debug {}
21
22impl<T: Eq + Hash + Clone + fmt::Debug> TextType for T {}
23
24#[derive(Debug, Clone, Hash, PartialEq, Eq)]
27#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
28pub struct Text<T, S = String> {
29 location: Point<T>,
31 text: S,
33}
34
35impl<T, S> fmt::Display for Text<T, S>
37where
38 T: fmt::Display,
39 S: TextType + fmt::Display,
40{
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 write!(f, "Text({}, {})", self.text, self.location)
43 }
44}
45
46impl<T, S> Deref for Text<T, S>
47where
48 S: Deref<Target = String>,
49{
50 type Target = String;
51
52 fn deref(&self) -> &Self::Target {
54 self.text.deref()
55 }
56}
57
58impl<T, S: TextType> Text<T, S> {
59 pub fn new(text: S, location: Point<T>) -> Self {
61 Text { location, text }
62 }
63
64 pub fn text(&self) -> &S {
66 &self.text
67 }
68}
69
70impl<T: Copy, S: TextType> Text<T, S> {
71 #[inline]
73 pub fn location(&self) -> Point<T> {
74 self.location
75 }
76
77 #[inline]
79 pub fn x(&self) -> T {
80 self.location.x
81 }
82
83 #[inline]
85 pub fn y(&self) -> T {
86 self.location.y
87 }
88}
89
90impl<T: Copy + PartialOrd, S> TryBoundingBox<T> for Text<T, S> {
91 fn try_bounding_box(&self) -> Option<Rect<T>> {
92 Some(Rect::new(self.location, self.location))
93 }
94}
95
96impl<T, Dst, S> TryCastCoord<T, Dst> for Text<T, S>
97where
98 T: Copy + NumCast,
99 Dst: Copy + NumCast,
100 S: Clone,
101{
102 type Output = Text<Dst, S>;
103
104 fn try_cast(&self) -> Option<Self::Output> {
105 self.location.try_cast().map(|loc| Text {
106 location: loc,
107 text: self.text.clone(),
108 })
109 }
110}
111
112impl<T, S> MapPointwise<T> for Text<T, S>
114where
115 T: Copy,
116 S: Clone,
117{
118 #[inline]
120 fn transform<F>(&self, transformation: F) -> Self
121 where
122 F: Fn(Point<T>) -> Point<T>,
123 {
124 Text {
125 location: transformation(self.location),
126 text: self.text.clone(),
127 }
128 }
129}