changepacks_node/
package.rs1use anyhow::Result;
2use async_trait::async_trait;
3use changepacks_core::{Language, Package, UpdateType};
4use changepacks_utils::{detect_indent, next_version};
5use serde::Serialize;
6use std::path::{Path, PathBuf};
7use tokio::fs::{read_to_string, write};
8
9#[derive(Debug)]
10pub struct NodePackage {
11 name: String,
12 version: String,
13 path: PathBuf,
14 relative_path: PathBuf,
15 is_changed: bool,
16}
17
18impl NodePackage {
19 pub fn new(name: String, version: String, path: PathBuf, relative_path: PathBuf) -> Self {
20 Self {
21 name,
22 version,
23 path,
24 relative_path,
25 is_changed: false,
26 }
27 }
28}
29
30#[async_trait]
31impl Package for NodePackage {
32 fn name(&self) -> &str {
33 &self.name
34 }
35
36 fn version(&self) -> &str {
37 &self.version
38 }
39
40 fn path(&self) -> &Path {
41 &self.path
42 }
43
44 fn relative_path(&self) -> &Path {
45 &self.relative_path
46 }
47
48 async fn update_version(&self, update_type: UpdateType) -> Result<()> {
49 let next_version = next_version(&self.version, update_type)?;
50
51 let package_json_raw = read_to_string(&self.path).await?;
52 let postfix = if package_json_raw.ends_with("\n") {
53 "\n"
54 } else {
55 ""
56 };
57 let indent = detect_indent(&package_json_raw);
58 let mut package_json: serde_json::Value = serde_json::from_str(&package_json_raw)?;
59 package_json["version"] = serde_json::Value::String(next_version);
60 let ind = &b" ".repeat(indent);
61 let formatter = serde_json::ser::PrettyFormatter::with_indent(ind);
62 let writer = Vec::new();
63 let mut ser = serde_json::Serializer::with_formatter(writer, formatter);
64 package_json.serialize(&mut ser)?;
65 write(
66 &self.path,
67 String::from_utf8(ser.into_inner())?.to_string() + postfix,
68 )
69 .await?;
70 Ok(())
71 }
72
73 fn language(&self) -> Language {
74 Language::Node
75 }
76
77 fn set_changed(&mut self, changed: bool) {
78 self.is_changed = changed;
79 }
80 fn is_changed(&self) -> bool {
81 self.is_changed
82 }
83}