ploit_malper/db/
content.rs1use std::fs;
2use std::path::{Path, PathBuf};
3
4use crate::config::config_dir;
5use crate::db::models::sha256_hex;
6use crate::error::Result;
7
8pub const MAX_DB_CONTENT: usize = 2000;
11
12pub fn content_dir() -> PathBuf {
15 config_dir().join("content")
16}
17
18pub fn store_content(content: &str) -> Result<(String, String)> {
21 let hash = sha256_hex(content);
22 let dir = content_dir();
23 fs::create_dir_all(&dir)?;
24 let abs = dir.join(&hash);
25 if !abs.exists() {
26 fs::write(&abs, content)?;
27 }
28 Ok((hash.clone(), format!("content/{}", hash)))
29}
30
31pub fn resolve_path(rel: &str) -> PathBuf {
33 config_dir().join(rel)
34}
35
36pub fn read_content(rel: &str) -> Result<String> {
38 Ok(fs::read_to_string(resolve_path(rel))?)
39}
40
41pub fn short_excerpt(content: &str, max: usize) -> String {
44 if content.chars().count() <= max {
45 return content.to_string();
46 }
47 let mut out: String = content.chars().take(max).collect();
48 out.push('…');
49 out
50}
51
52pub fn is_short(content: &str) -> bool {
54 content.len() <= MAX_DB_CONTENT
55}
56
57pub fn store_or_excerpt(content: &str) -> Result<(String, Option<String>)> {
61 if is_short(content) {
62 return Ok((content.to_string(), None));
63 }
64 let (_, rel) = store_content(content)?;
65 Ok((short_excerpt(content, MAX_DB_CONTENT), Some(rel)))
66}
67
68pub fn is_content_rel(path: &Path) -> bool {
70 path.starts_with("content")
71}