1#![allow(unexpected_cfgs)]
6
7use std::fs;
8use std::path::Path;
9
10#[allow(dead_code)]
11#[cfg(feature = "svg_render")]
12use super::image::ImageResult;
13
14#[derive(Debug, Clone, Default)]
16pub struct SvgRenderOptions {
17 pub width: Option<u32>,
18 pub height: Option<u32>,
19 pub dpi: Option<u32>,
20 pub background: Option<String>,
21}
22
23pub const DEFAULT_SVG_DPI: u32 = 96;
25
26pub fn is_svg_render_enabled() -> bool {
28 std::env::var("ASTER_SVG_RENDER")
29 .map(|v| v != "false")
30 .unwrap_or(true)
31}
32
33pub fn validate_svg_file(file_path: &Path) -> Result<(), String> {
35 if !file_path.exists() {
36 return Err("File does not exist".to_string());
37 }
38
39 let metadata =
40 fs::metadata(file_path).map_err(|e| format!("Failed to read metadata: {}", e))?;
41
42 if metadata.len() == 0 {
43 return Err("SVG file is empty".to_string());
44 }
45
46 let content =
47 fs::read_to_string(file_path).map_err(|e| format!("Failed to read file: {}", e))?;
48
49 if !content.contains("<svg") && !content.contains("<?xml") {
50 return Err("File does not appear to be a valid SVG".to_string());
51 }
52
53 Ok(())
54}
55
56pub fn get_svg_dimensions(svg_path: &Path) -> Option<(u32, u32)> {
58 let content = fs::read_to_string(svg_path).ok()?;
59
60 let width = extract_dimension(&content, "width");
62 let height = extract_dimension(&content, "height");
63
64 match (width, height) {
65 (Some(w), Some(h)) => Some((w, h)),
66 _ => None,
67 }
68}
69
70fn extract_dimension(content: &str, attr: &str) -> Option<u32> {
71 let pattern = format!(r#"{}=["'](\d+(?:\.\d+)?)"#, attr);
72 let re = regex::Regex::new(&pattern).ok()?;
73 let caps = re.captures(content)?;
74 caps.get(1)?.as_str().parse::<f64>().ok().map(|v| v as u32)
75}
76
77pub fn read_svg_file(file_path: &Path) -> Result<String, String> {
79 validate_svg_file(file_path)?;
80 fs::read_to_string(file_path).map_err(|e| format!("Failed to read SVG file: {}", e))
81}
82
83#[allow(unexpected_cfgs)]
86#[cfg(feature = "svg_render")]
87pub fn render_svg_to_png(
88 svg_path: &Path,
89 _options: SvgRenderOptions,
90) -> Result<ImageResult, String> {
91 use base64::{engine::general_purpose::STANDARD, Engine};
92
93 let content = read_svg_file(svg_path)?;
94 let original_size = content.len() as u64;
95
96 Err("SVG rendering requires resvg feature".to_string())
99}
100
101#[allow(unexpected_cfgs)]
103#[cfg(feature = "svg_render")]
104pub fn render_svg_string_to_png(
105 _svg_string: &str,
106 _options: SvgRenderOptions,
107) -> Result<ImageResult, String> {
108 Err("SVG rendering requires resvg feature".to_string())
109}