use std::fs;
use std::path::Path;
use std::str;
use std::fs::Metadata;
use std::ops::Deref;
use sha2::{Digest, Sha256};
use serde::{Deserialize, Serialize};
use crate::errors::CarboneError;
use crate::types::*;
use crate::types::Result;
#[derive(Debug, Clone)]
pub struct TemplateFile {
path: String,
pub content: Option<Vec<u8>>,
pub metadata: Metadata,
}
impl TemplateFile {
pub fn new(path: String, content: Option<Vec<u8>>) -> Result<Self> {
if Path::new(path.as_str()).is_dir() {
return Err(CarboneError::IsADirectory(path));
}
if !Path::new(path.as_str()).is_file() {
return Err(CarboneError::TemplateFileNotFound(path));
}
let metadata = fs::metadata(path.as_str())?;
Ok(Self {
path,
content,
metadata,
})
}
pub fn generate_id(&self, payload: Option<&str>) -> Result<TemplateId> {
let file_content = match self.content.to_owned() {
Some(c) => c,
None => fs::read(self.path_as_str())?,
};
TemplateId::from_bytes(file_content, payload)
}
pub fn path_as_str(&self) -> &str {
&self.path
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub struct TemplateId(Id);
impl TemplateId {
pub fn new<T: Into<String>>(id: T) -> Result<Self> {
let id = Id::new(id, "template_id")?;
Ok(TemplateId(id))
}
pub fn from_bytes(data: Vec<u8>, payload: Option<&str>) -> Result<Self> {
let mut sha256 = Sha256::new();
let payload = payload.unwrap_or("");
sha256.update(payload);
sha256.update(data);
let result: String = format!("{:X}", sha256.finalize());
Self::new(result.to_lowercase())
}
}
impl Deref for TemplateId {
type Target = Id;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl AsRef<str> for TemplateId {
fn as_ref(&self) -> &str {
self.0.as_ref()
}
}