ass_editor/formats/
traits.rs1use super::{FormatInfo, FormatOptions, FormatResult};
7use crate::core::{EditorDocument, EditorError};
8use std::fmt;
9use std::io::{Read, Write};
10use std::path::Path;
11
12pub trait FormatImporter: fmt::Debug + Send + Sync {
14 fn format_info(&self) -> &FormatInfo;
16
17 fn can_import(&self, extension: &str) -> bool {
19 self.format_info()
20 .extensions
21 .iter()
22 .any(|ext| ext.eq_ignore_ascii_case(extension))
23 }
24
25 fn import_from_reader(
27 &self,
28 reader: &mut dyn Read,
29 options: &FormatOptions,
30 ) -> Result<(EditorDocument, FormatResult), EditorError>;
31
32 fn import_from_path(
34 &self,
35 path: &Path,
36 options: &FormatOptions,
37 ) -> Result<(EditorDocument, FormatResult), EditorError> {
38 let mut file = std::fs::File::open(path)
39 .map_err(|e| EditorError::IoError(format!("Failed to open file: {e}")))?;
40 self.import_from_reader(&mut file, options)
41 }
42
43 fn import_from_string(
45 &self,
46 content: &str,
47 options: &FormatOptions,
48 ) -> Result<(EditorDocument, FormatResult), EditorError> {
49 let mut cursor = std::io::Cursor::new(content.as_bytes());
50 self.import_from_reader(&mut cursor, options)
51 }
52}
53
54pub trait FormatExporter: fmt::Debug + Send + Sync {
56 fn format_info(&self) -> &FormatInfo;
58
59 fn can_export(&self, extension: &str) -> bool {
61 self.format_info()
62 .extensions
63 .iter()
64 .any(|ext| ext.eq_ignore_ascii_case(extension))
65 }
66
67 fn export_to_writer(
69 &self,
70 document: &EditorDocument,
71 writer: &mut dyn Write,
72 options: &FormatOptions,
73 ) -> Result<FormatResult, EditorError>;
74
75 fn export_to_path(
77 &self,
78 document: &EditorDocument,
79 path: &Path,
80 options: &FormatOptions,
81 ) -> Result<FormatResult, EditorError> {
82 let mut file = std::fs::File::create(path)
83 .map_err(|e| EditorError::IoError(format!("Failed to create file: {e}")))?;
84 self.export_to_writer(document, &mut file, options)
85 }
86
87 fn export_to_string(
89 &self,
90 document: &EditorDocument,
91 options: &FormatOptions,
92 ) -> Result<(String, FormatResult), EditorError> {
93 let mut buffer = Vec::new();
94 let result = self.export_to_writer(document, &mut buffer, options)?;
95 let content = String::from_utf8(buffer)
96 .map_err(|e| EditorError::InvalidFormat(format!("Invalid UTF-8 output: {e}")))?;
97 Ok((content, result))
98 }
99}
100
101pub trait Format: FormatImporter + FormatExporter {
103 fn name(&self) -> &str {
105 &FormatImporter::format_info(self).name
106 }
107
108 fn supports_extension(&self, extension: &str) -> bool {
110 self.can_import(extension) || self.can_export(extension)
111 }
112
113 fn as_importer(&self) -> &dyn FormatImporter;
115
116 fn as_exporter(&self) -> &dyn FormatExporter;
118}