tfc_toolset_extras/file/
tag.rs1use crate::ExtrasError;
2use serde::{Deserialize, Serialize};
3use std::{fs::File, io::BufReader, path::Path};
4use tfc_toolset::{
5 error::ToolError,
6 tag::Attributes,
7 workspace::{Workspace, WorkspaceTags},
8};
9
10#[derive(Clone, Debug, Deserialize, Serialize)]
11pub struct Tag {
12 #[serde(skip_serializing_if = "Option::is_none")]
13 pub id: Option<String>,
14 #[serde(skip_serializing_if = "Option::is_none")]
15 pub name: Option<String>,
16 #[serde(skip_serializing_if = "Option::is_none")]
17 pub attributes: Option<Attributes>,
18 pub workspace: Option<Workspace>,
19}
20
21#[derive(Clone, Debug, Deserialize, Serialize)]
22pub struct TagsFile {
23 #[serde(skip_serializing_if = "Option::is_none")]
24 pub tags: Option<Vec<Tag>>,
25}
26
27impl From<Vec<WorkspaceTags>> for TagsFile {
28 fn from(vec: Vec<WorkspaceTags>) -> Self {
29 let mut tags_file = TagsFile { tags: None };
30 let mut tags_vec = Vec::new();
31 for workspace_tags in vec {
32 for tag_vec in workspace_tags.tags {
33 for tag in tag_vec.data {
34 let entry = Tag {
35 id: tag.id,
36 name: Some(tag.attributes.name.clone()), attributes: Some(tag.attributes),
38 workspace: Some(workspace_tags.workspace.clone()),
39 };
40 tags_vec.push(entry);
41 }
42 }
43 }
44 tags_file.tags = Some(tags_vec);
45 tags_file
46 }
47}
48
49impl TagsFile {
50 pub fn load<P: AsRef<Path>>(path: P) -> Result<Self, ExtrasError> {
51 let file = File::open(path).map_err(ToolError::Io)?;
52 let reader = BufReader::new(file);
53 let tags_file: Self =
54 serde_json::from_reader(reader).map_err(ToolError::Json)?;
55 Ok(tags_file)
56 }
57
58 pub fn save<P: AsRef<Path>>(
59 &self,
60 path: P,
61 pretty: bool,
62 ) -> Result<(), ToolError> {
63 if pretty {
64 serde_json::to_writer_pretty(&File::create(path)?, self)?;
65 } else {
66 serde_json::to_writer(&File::create(path)?, self)?;
67 }
68 Ok(())
69 }
70}