ppt_rs/
api.rs

1//! Public API module
2//!
3//! High-level API for working with PowerPoint presentations.
4
5use crate::exc::{Result, PptxError};
6use crate::opc::Package;
7use crate::generator::{SlideContent, create_pptx_with_content};
8use std::io::{Read, Seek};
9use std::path::Path;
10
11/// Represents a PowerPoint presentation
12#[derive(Debug, Clone, Default)]
13pub struct Presentation {
14    title: String,
15    slides: Vec<SlideContent>,
16}
17
18impl Presentation {
19    /// Create a new empty presentation
20    pub fn new() -> Self {
21        Presentation {
22            title: String::new(),
23            slides: Vec::new(),
24        }
25    }
26
27    /// Create a presentation with a title
28    pub fn with_title(title: &str) -> Self {
29        Presentation {
30            title: title.to_string(),
31            slides: Vec::new(),
32        }
33    }
34
35    /// Set the presentation title
36    pub fn title(mut self, title: &str) -> Self {
37        self.title = title.to_string();
38        self
39    }
40
41    /// Add a slide to the presentation
42    pub fn add_slide(mut self, slide: SlideContent) -> Self {
43        self.slides.push(slide);
44        self
45    }
46
47    /// Get the number of slides
48    pub fn slide_count(&self) -> usize {
49        self.slides.len()
50    }
51
52    /// Get the presentation title
53    pub fn get_title(&self) -> &str {
54        &self.title
55    }
56
57    /// Build the presentation as PPTX bytes
58    pub fn build(&self) -> Result<Vec<u8>> {
59        if self.slides.is_empty() {
60            return Err(PptxError::InvalidState("Presentation has no slides".into()));
61        }
62        create_pptx_with_content(&self.title, self.slides.clone())
63            .map_err(|e| PptxError::Generic(e.to_string()))
64    }
65
66    /// Save the presentation to a file
67    pub fn save<P: AsRef<Path>>(&self, path: P) -> Result<()> {
68        let data = self.build()?;
69        std::fs::write(path, data)?;
70        Ok(())
71    }
72}
73
74/// Open a presentation from a file path
75pub fn open<P: AsRef<Path>>(path: P) -> Result<Package> {
76    Package::open(path)
77}
78
79/// Open a presentation from a reader
80pub fn open_reader<R: Read + Seek>(reader: R) -> Result<Package> {
81    Package::open_reader(reader)
82}
83
84#[cfg(test)]
85mod tests {
86    use super::*;
87
88    #[test]
89    fn test_presentation_builder() {
90        let pres = Presentation::with_title("Test")
91            .add_slide(SlideContent::new("Slide 1").add_bullet("Point 1"));
92        
93        assert_eq!(pres.get_title(), "Test");
94        assert_eq!(pres.slide_count(), 1);
95    }
96
97    #[test]
98    fn test_presentation_build() {
99        let pres = Presentation::with_title("Test")
100            .add_slide(SlideContent::new("Slide 1"));
101        
102        let result = pres.build();
103        assert!(result.is_ok());
104    }
105}