1#[cfg(not(feature = "tokio"))]
8use std::sync::mpsc::Sender;
9#[cfg(feature = "tokio")]
10use tokio::sync::mpsc::UnboundedSender as Sender;
11
12use image::Rgba;
13use ratatui::prelude::{Buffer, Rect};
14
15use crate::{
16 Resize, ResizeEncodeRender,
17 errors::Errors,
18 protocol::{StatefulProtocol, StatefulProtocolType},
19};
20
21pub struct ResizeRequest {
23 protocol: StatefulProtocol,
24 resize: Resize,
25 area: Rect,
26 id: u64,
27}
28
29impl ResizeRequest {
30 pub fn resize_encode(mut self) -> Result<ResizeResponse, Errors> {
31 self.protocol.resize_encode(&self.resize, self.area);
32 self.protocol
33 .last_encoding_result()
34 .expect("The resize has just been performed")?;
35 Ok(ResizeResponse {
36 protocol: self.protocol,
37 id: self.id,
38 })
39 }
40}
41
42pub struct ResizeResponse {
44 protocol: StatefulProtocol,
45 id: u64,
46}
47
48pub struct ThreadProtocol {
53 inner: Option<StatefulProtocol>,
54 tx: Sender<ResizeRequest>,
55 id: u64,
56}
57
58impl ThreadProtocol {
59 pub fn new(tx: Sender<ResizeRequest>, inner: Option<StatefulProtocol>) -> ThreadProtocol {
60 Self { inner, tx, id: 0 }
61 }
62
63 pub fn replace_protocol(&mut self, proto: StatefulProtocol) {
64 self.inner = Some(proto);
65 self.increment_id();
66 }
67
68 pub fn protocol_type(&self) -> Option<&StatefulProtocolType> {
69 self.inner.as_ref().map(|inner| inner.protocol_type())
70 }
71
72 pub fn protocol_type_owned(self) -> Option<StatefulProtocolType> {
73 self.inner.map(|inner| inner.protocol_type_owned())
74 }
75
76 pub fn background_color(&self) -> Option<Rgba<u8>> {
78 self.inner.as_ref().map(|inner| inner.background_color())
79 }
80
81 pub fn empty_protocol(&mut self) {
83 self.inner = None;
84 self.increment_id();
85 }
86
87 pub fn update_resized_protocol(&mut self, completed: ResizeResponse) -> bool {
88 let equal = self.id == completed.id;
89 if equal {
90 self.inner = Some(completed.protocol)
91 }
92 equal
93 }
94
95 pub fn size_for(&self, resize: Resize, area: Rect) -> Option<Rect> {
96 self.inner
97 .as_ref()
98 .map(|protocol| protocol.size_for(resize, area))
99 }
100
101 fn increment_id(&mut self) {
102 self.id = self.id.wrapping_add(1);
103 }
104}
105
106impl ResizeEncodeRender for ThreadProtocol {
107 fn needs_resize(&self, resize: &Resize, area: Rect) -> Option<Rect> {
108 self.inner
109 .as_ref()
110 .and_then(|protocol| protocol.needs_resize(resize, area))
111 }
112
113 fn resize_encode(&mut self, resize: &Resize, area: Rect) {
115 let _ = self.inner.take().map(|protocol| {
116 self.increment_id();
117 _ = self.tx.send(ResizeRequest {
118 protocol,
119 resize: resize.clone(),
120 area,
121 id: self.id,
122 });
123 });
124 }
125
126 fn render(&mut self, area: Rect, buf: &mut Buffer) {
128 let _ = self
129 .inner
130 .as_mut()
131 .map(|protocol| protocol.render(area, buf));
132 }
133}