svgbob/buffer/cell_buffer/
contacts.rs1use super::{endorse, endorse::Endorse};
2use crate::{
3 buffer::{fragment::Fragment, fragment_buffer::FragmentSpan, Cell, Span},
4 Merge,
5};
6use std::fmt;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct Contacts(pub Vec<FragmentSpan>);
12
13impl AsRef<Vec<FragmentSpan>> for Contacts {
14 fn as_ref(&self) -> &Vec<FragmentSpan> {
15 &self.0
16 }
17}
18
19impl AsMut<Vec<FragmentSpan>> for Contacts {
20 fn as_mut(&mut self) -> &mut Vec<FragmentSpan> {
21 &mut self.0
22 }
23}
24
25impl Contacts {
26 pub(crate) fn new(fragment: FragmentSpan) -> Self {
27 Contacts(vec![fragment])
28 }
29
30 pub fn fragments(&self) -> Vec<&Fragment> {
31 self.0.iter().map(|fs| &fs.fragment).collect()
32 }
33
34 pub fn cells(&self) -> Vec<Cell> {
35 self.0.iter().flat_map(|fs| fs.cells()).collect()
36 }
37
38 pub fn span(&self) -> Span {
39 let cell_chars: Vec<(Cell, char)> =
40 self.0.iter().flat_map(|fs| fs.span.0.clone()).collect();
41 cell_chars.into()
42 }
43
44 pub(crate) fn is_contacting_frag(&self, other_frag: &FragmentSpan) -> bool {
48 self.as_ref()
49 .iter()
50 .rev()
51 .any(|frag| frag.is_contacting(other_frag))
52 }
53
54 pub(crate) fn is_contacting(&self, other: &Self) -> bool {
55 other
56 .as_ref()
57 .iter()
58 .any(|other_frag| self.is_contacting_frag(other_frag))
59 }
60
61 pub(crate) fn endorse_rect(&self) -> Option<Fragment> {
67 let fragments = self.fragments();
68 if let Some(rect) = endorse::endorse_rect(&fragments) {
69 Some(rect.into())
70 } else {
71 endorse::endorse_rounded_rect(&fragments)
72 .map(|rounded_rect| rounded_rect.into())
73 }
74 }
75
76 pub(crate) fn endorse_rects(
82 contacts: Vec<Contacts>,
83 ) -> Endorse<FragmentSpan, Contacts> {
84 let mut accepted = vec![];
85 let mut rejects: Vec<Contacts> = vec![];
86 for contact in contacts {
87 if let Some(fragment) = contact.endorse_rect() {
88 let span = contact.span();
89 let fragment_span = FragmentSpan::new(span, fragment);
90 accepted.push(fragment_span);
91 } else {
92 rejects.push(contact);
93 }
94 }
95 Endorse { accepted, rejects }
96 }
97
98 pub(crate) fn absolute_position(&self, cell: Cell) -> Self {
99 Contacts(
100 self.as_ref()
101 .iter()
102 .map(|frag| frag.absolute_position(cell))
103 .collect(),
104 )
105 }
106
107 pub fn is_bounded(&self, bound1: Cell, bound2: Cell) -> bool {
108 self.cells()
109 .iter()
110 .all(|cell| cell.is_bounded(bound1, bound2))
111 }
112
113 pub fn hit_cell(&self, needle: Cell) -> bool {
114 self.cells().iter().any(|cell| *cell == needle)
115 }
116}
117
118impl Merge for Contacts {
119 fn merge(&self, other: &Self) -> Option<Self> {
120 if self.is_contacting(&other) {
121 let mut fragment_spans: Vec<FragmentSpan> = self.0.clone();
122 fragment_spans.extend_from_slice(&other.0);
123 Some(Contacts(fragment_spans))
124 } else {
125 None
126 }
127 }
128}
129
130impl fmt::Display for Contacts {
131 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
132 for frag in self.as_ref().iter() {
133 writeln!(f, "\t{}", frag)?;
134 }
135 Ok(())
136 }
137}