vmf_forge/vmf_file/io.rs
1use std::{
2 fs::File,
3 io::{Read, Write},
4 path::Path,
5 str::FromStr,
6};
7
8use crate::{VmfError, VmfResult, parser};
9
10use super::VmfFile;
11
12impl VmfFile {
13 /// Parses a VMF file from a string.
14 ///
15 /// # Arguments
16 ///
17 /// * `content` - The string content of the VMF file.
18 ///
19 /// # Returns
20 ///
21 /// A `VmfResult` containing the parsed `VmfFile` or a `VmfError` if parsing fails.
22 ///
23 /// # Examples
24 ///
25 /// ```
26 /// use vmf_forge::VmfFile;
27 ///
28 /// let vmf_content = r#"
29 /// versioninfo
30 /// {
31 /// "editorversion" "400"
32 /// "editorbuild" "8000"
33 /// "mapversion" "1"
34 /// "formatversion" "100"
35 /// "prefab" "0"
36 /// }
37 /// "#;
38 ///
39 /// let vmf_file = VmfFile::parse(vmf_content);
40 /// assert!(vmf_file.is_ok());
41 /// ```
42 pub fn parse(content: &str) -> VmfResult<Self> {
43 parser::parse_vmf(content)
44 }
45
46 /// Parses a VMF file from a `File`.
47 ///
48 /// # Arguments
49 ///
50 /// * `file` - The `File` to read from.
51 ///
52 /// # Returns
53 ///
54 /// A `VmfResult` containing the parsed `VmfFile` or a `VmfError` if parsing fails.
55 ///
56 /// # Examples
57 ///
58 /// ```no_run
59 /// use vmf_forge::VmfFile;
60 /// use std::fs::File;
61 ///
62 /// let mut file = File::open("your_map.vmf").unwrap();
63 /// let vmf_file = VmfFile::parse_file(&mut file);
64 /// assert!(vmf_file.is_ok());
65 /// ```
66 pub fn parse_file(file: &mut impl Read) -> VmfResult<Self> {
67 let mut content = Vec::new();
68 file.read_to_end(&mut content)?;
69 let content = String::from_utf8_lossy(&content);
70
71 VmfFile::parse(&content)
72 }
73
74 /// Opens and parses a VMF file from a file path.
75 ///
76 /// # Arguments
77 ///
78 /// * `path` - The path to the VMF file.
79 ///
80 /// # Returns
81 ///
82 /// A `VmfResult` containing the parsed `VmfFile` or a `VmfError` if an error occurs.
83 ///
84 /// # Examples
85 ///
86 /// ```no_run
87 /// use vmf_forge::VmfFile;
88 ///
89 /// let vmf_file = VmfFile::open("your_map.vmf");
90 /// assert!(vmf_file.is_ok());
91 /// ```
92 pub fn open(path: impl AsRef<Path>) -> VmfResult<Self> {
93 let path_str = path.as_ref().to_string_lossy().to_string();
94 let mut file = File::open(path)?;
95 let mut content = Vec::new();
96 file.read_to_end(&mut content)?;
97 let content = String::from_utf8_lossy(&content);
98
99 let mut vmf_file = VmfFile::parse(&content)?;
100 vmf_file.path = Some(path_str);
101 Ok(vmf_file)
102 }
103
104 /// Saves the `VmfFile` to a file at the specified path.
105 ///
106 /// # Arguments
107 ///
108 /// * `path` - The path to save the VMF file to.
109 ///
110 /// # Returns
111 ///
112 /// A `VmfResult` indicating success or a `VmfError` if an error occurs.
113 ///
114 /// # Examples
115 ///
116 /// ```no_run
117 /// use vmf_forge::VmfFile;
118 ///
119 /// let vmf_file = VmfFile::open("your_map.vmf").unwrap();
120 /// let result = vmf_file.save("new_map.vmf");
121 /// assert!(result.is_ok());
122 /// ```
123 pub fn save(&self, path: impl AsRef<Path>) -> VmfResult<()> {
124 let mut file = File::create(path)?;
125 file.write_all(self.to_vmf_string().as_bytes())?;
126 Ok(())
127 }
128}
129
130impl FromStr for VmfFile {
131 type Err = VmfError;
132
133 fn from_str(s: &str) -> Result<Self, Self::Err> {
134 VmfFile::parse(s)
135 }
136}