1use std::{
2 fmt,
3 sync::Arc,
4};
5use crate::{
6 Reference,
7 aim::{WorkflowLike, Writer, WriterLike}, values::Node,
8};
9use anyhow::Result;
10use jiff::civil::DateTime;
11use jiff::fmt::strtime;
12use jiff::tz::TimeZone;
13
14#[derive(Debug, Clone, PartialEq)]
15pub struct Sheet {
16 pub locator: Arc<Reference>,
17 pub path: Arc<str>,
18 pub date: DateTime,
19 pub version: u32,
20 pub minor_version: u32,
21 pub first_version: u32,
22 pub latest_version: u32,
23 pub model: Arc<str>,
24 pub pattern: Arc<str>,
25 pub length: u32,
26}
27
28impl Sheet {
29 #[doc = include_str!("../docs/sheet/convert.md")]
31 pub fn convert(node: &Node) -> Result<Self> {
32 let workflow = node.get_workflow()?;
33 let locator = workflow.locator();
34 let path_buf = locator.to_path();
35 let path: Arc<str> = Arc::from(path_buf.to_string_lossy());
36 Ok(Self {
37 locator,
38 path,
39 date: workflow.date(),
40 version: workflow.version(),
41 minor_version: workflow.minor_version(),
42 first_version: workflow.first_version(),
43 latest_version: workflow.latest_version(),
44 model: Arc::from(node.inference().model().as_str()),
45 pattern: Arc::from(node.inference().pattern().as_str()),
46 length: workflow.row_count() as u32,
47 })
48 }
49
50 pub fn locator(&self) -> &Arc<Reference> {
51 &self.locator
52 }
53
54 pub fn path(&self) -> &Arc<str> {
55 &self.path
56 }
57
58 pub fn date(&self) -> &DateTime {
59 &self.date
60 }
61
62 pub fn version(&self) -> u32 {
63 self.version
64 }
65
66 pub fn minor_version(&self) -> u32 {
67 self.minor_version
68 }
69
70 pub fn first_version(&self) -> u32 {
71 self.first_version
72 }
73
74 pub fn latest_version(&self) -> u32 {
75 self.latest_version
76 }
77
78 pub fn model(&self) -> &Arc<str> {
79 &self.model
80 }
81
82 pub fn pattern(&self) -> &Arc<str> {
83 &self.pattern
84 }
85
86 pub fn length(&self) -> u32 {
87 self.length
88 }
89
90 pub fn is_empty(&self) -> bool {
91 self.length == 0
92 }
93
94 #[doc = include_str!("../docs/sheet/print.md")]
96 pub fn print(&self, writer: &mut Writer) {
97 writer.write_str("=== SHEET START ==="); writer.write_eol();
98 writer.write_str("- locator: "); self.locator.print(writer); writer.write_eol();
99 writer.write_str("- path: "); writer.print(&self.path); writer.write_eol();
100 writer.write_str("- date: "); writer.write_date(&self.date); writer.write_eol();
101 writer.write_str("- version: "); writer.write_unsigned(self.version); writer.write_eol();
102 writer.write_str("- minor_version: "); writer.write_unsigned(self.minor_version); writer.write_eol();
103 writer.write_str("- first_version: "); writer.write_unsigned(self.first_version); writer.write_eol();
104 writer.write_str("- latest_version: "); writer.write_unsigned(self.latest_version); writer.write_eol();
105 writer.write_str("- model: "); writer.print(&self.model); writer.write_eol();
106 writer.write_str("- pattern: "); writer.print(&self.pattern); writer.write_eol();
107 writer.write_str("- length: "); writer.write_unsigned(self.length); writer.write_eol();
108 writer.write_str("=== SHEET END ==="); writer.write_eol();
109 }
110
111 #[doc = include_str!("../docs/sheet/to_formula.md")]
113 pub fn to_formula(&self) -> String {
114 let mut writer = Writer::formulizer();
115 self.print(&mut writer);
116 writer.finish()
117 }
118
119 pub fn custom_format_date(&self, format: &str) -> String {
141 let date = if let Ok(zoned) = self.date.to_zoned(TimeZone::system()) {
142 zoned.datetime()
143 } else {
144 self.date
145 };
146 if let Ok(result) = strtime::format(format, date) {
147 result
148 } else {
149 let mut writer = Writer::stringizer();
150 writer.write_date(&date);
151 writer.finish()
152 }
153 }
154
155pub fn format_date(&self) -> String {
176 self.custom_format_date("%A, %d/%m/%y %I:%M %p")
177 }
178}
179
180impl WriterLike for Sheet {
181 fn write(&self, writer: &mut Writer) {
182 self.print(writer);
183 }
184}
185
186impl fmt::Display for Sheet {
187 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
188 write!(f, "{}", self.to_stringized())
189 }
190}