acorn/schema/standard/
text.rs1#[cfg(feature = "std")]
6use crate::error::ApiResult;
7#[cfg(feature = "std")]
8use crate::io::document::{DocumentFormat, SourceDocument};
9#[cfg(feature = "std")]
10use crate::io::{read_file, write_file, InputOutput};
11use crate::prelude::*;
12#[cfg(feature = "std")]
13use crate::prelude::{Path, PathBuf};
14#[cfg(feature = "std")]
15use crate::util::file_extension;
16#[cfg(feature = "std")]
17use crate::util::MimeType;
18use crate::util::{MarkdownSupport, ToProse, Unstructured};
19#[cfg(feature = "std")]
20use color_eyre::eyre::eyre;
21use schemars::JsonSchema;
22use serde::{Deserialize, Serialize};
23use validator::Validate;
24
25#[derive(Clone, Debug, Default, Deserialize, JsonSchema, PartialEq, Serialize, Validate)]
27#[serde(transparent)]
28pub struct Docx {
29 pub content: String,
31}
32#[derive(Clone, Debug, Default, Deserialize, JsonSchema, PartialEq, Serialize, Validate)]
34#[serde(transparent)]
35pub struct Text {
36 pub content: String,
38}
39impl From<&str> for Text {
40 fn from(content: &str) -> Self {
41 Self {
42 content: content.to_string(),
43 }
44 }
45}
46impl From<String> for Text {
47 fn from(content: String) -> Self {
48 Self { content }
49 }
50}
51#[cfg(feature = "std")]
52impl TryFrom<&Path> for Text {
53 type Error = color_eyre::Report;
54
55 fn try_from(path: &Path) -> Result<Self, Self::Error> {
56 Self::read(path.to_path_buf())
57 }
58}
59#[cfg(feature = "std")]
60impl InputOutput for Text {
61 fn read(path: impl Into<PathBuf>) -> ApiResult<Self> {
62 let source = path.into();
63 match MimeType::from(source.display().to_string()) {
64 | MimeType::Markdown | MimeType::Text => Self::read_text(source),
65 | MimeType::Json => Self::read_json(source),
66 | MimeType::Yaml => Self::read_yaml(source),
67 | _ => Err(eyre!("Unsupported plain text file extension")),
68 }
69 }
70 fn read_json(path: PathBuf) -> ApiResult<Self> {
71 Self::read_text(path)
72 }
73 fn read_markdown(path: PathBuf) -> ApiResult<Self> {
74 Self::read_text(path)
75 }
76 fn read_yaml(path: PathBuf) -> ApiResult<Self> {
77 Self::read_text(path)
78 }
79 fn write(&self, path: impl Into<PathBuf>) -> ApiResult<()> {
80 let output = path.into();
81 match MimeType::from(output.display().to_string()) {
82 | MimeType::Markdown | MimeType::Text => self.write_text(output),
83 | MimeType::Json => self.write_json(output),
84 | MimeType::Yaml => self.write_yaml(output),
85 | _ => Err(eyre!("Unsupported plain text file extension for writing")),
86 }
87 }
88 fn write_json(&self, path: impl Into<PathBuf>) -> ApiResult<()> {
89 self.write_text(path)
90 }
91 fn write_markdown(&self, path: impl Into<PathBuf>) -> ApiResult<()> {
92 self.write_text(path)
93 }
94 fn write_yaml(&self, path: impl Into<PathBuf>) -> ApiResult<()> {
95 self.write_text(path)
96 }
97}
98#[cfg(feature = "std")]
99impl InputOutput for Docx {
100 fn read(path: impl Into<PathBuf>) -> ApiResult<Self> {
101 let source = path.into();
102 match DocumentFormat::try_from(&MimeType::from(source.display().to_string())) {
103 | Ok(_) => Self::read_docx(source),
104 | Err(_) => match file_extension(source.display().to_string()).as_deref() {
105 | Some("md") | Some("markdown") | Some("txt") | Some("json") | Some("yml") | Some("yaml") => Self::read_text(source),
106 | _ => Err(eyre!("Unsupported document file extension")),
107 },
108 }
109 }
110 fn read_json(path: PathBuf) -> ApiResult<Self> {
111 Self::read_text(path)
112 }
113 fn read_markdown(path: PathBuf) -> ApiResult<Self> {
114 Self::read_text(path)
115 }
116 fn read_yaml(path: PathBuf) -> ApiResult<Self> {
117 Self::read_text(path)
118 }
119 fn write(&self, path: impl Into<PathBuf>) -> ApiResult<()> {
120 let output = path.into();
121 match file_extension(output.display().to_string()).as_deref() {
122 | Some("md") | Some("markdown") | Some("txt") | Some("json") | Some("yml") | Some("yaml") => self.write_text(output),
123 | Some("docx") => Err(eyre!("DOCX writing is not implemented")),
124 | _ => Err(eyre!("Unsupported DOCX file extension for writing")),
125 }
126 }
127 fn write_json(&self, path: impl Into<PathBuf>) -> ApiResult<()> {
128 self.write_text(path)
129 }
130 fn write_markdown(&self, path: impl Into<PathBuf>) -> ApiResult<()> {
131 self.write_text(path)
132 }
133 fn write_yaml(&self, path: impl Into<PathBuf>) -> ApiResult<()> {
134 self.write_text(path)
135 }
136}
137impl MarkdownSupport for Docx {
138 fn to_markdown(&self) -> String {
139 self.content().to_string()
140 }
141}
142impl MarkdownSupport for Text {
143 fn to_markdown(&self) -> String {
144 self.content().to_string()
145 }
146}
147impl ToProse for Docx {
148 fn to_prose(&self) -> String {
149 self.content().to_string()
150 }
151}
152impl ToProse for Text {
153 fn to_prose(&self) -> String {
154 self.content().to_string()
155 }
156}
157impl Unstructured for Docx {
158 fn content(&self) -> &str {
159 &self.content
160 }
161}
162impl Unstructured for Text {
163 fn content(&self) -> &str {
164 &self.content
165 }
166}
167#[cfg(feature = "std")]
168impl Docx {
169 fn read_docx(path: impl Into<PathBuf>) -> ApiResult<Self> {
170 SourceDocument::at(path).extract().map(|content| Self { content })
171 }
172 fn read_text(path: impl Into<PathBuf>) -> ApiResult<Self> {
173 read_file(path.into()).map(|content| Self { content })
174 }
175 fn write_text(&self, path: impl Into<PathBuf>) -> ApiResult<()> {
176 write_file(path, self.content().to_string())
177 }
178}
179#[cfg(feature = "std")]
180impl Text {
181 fn read_text(path: impl Into<PathBuf>) -> ApiResult<Self> {
182 read_file(path.into()).map(|content| Self { content })
183 }
184 fn write_text(&self, path: impl Into<PathBuf>) -> ApiResult<()> {
185 write_file(path, self.content().to_string())
186 }
187}