Skip to main content

ppt_rs/parts/
base.rs

1//! Base part trait and types
2//!
3//! Defines the common interface for all package parts.
4
5use crate::exc::PptxError;
6
7/// Content types for package parts
8#[derive(Debug, Clone, PartialEq)]
9pub enum ContentType {
10    Presentation,
11    Slide,
12    SlideLayout,
13    SlideMaster,
14    Theme,
15    NotesSlide,
16    NotesMaster,
17    Image(String), // format: png, jpeg, gif, etc.
18    Media(String), // format: mp4, mp3, etc.
19    Chart,
20    Table,
21    CoreProperties,
22    ExtendedProperties,
23    ContentTypes,
24    Relationships,
25    Xml,
26}
27
28impl ContentType {
29    /// Get the MIME type string
30    pub fn mime_type(&self) -> &'static str {
31        match self {
32            ContentType::Presentation => "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml",
33            ContentType::Slide => "application/vnd.openxmlformats-officedocument.presentationml.slide+xml",
34            ContentType::SlideLayout => "application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml",
35            ContentType::SlideMaster => "application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml",
36            ContentType::Theme => "application/vnd.openxmlformats-officedocument.theme+xml",
37            ContentType::NotesSlide => "application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml",
38            ContentType::NotesMaster => "application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml",
39            ContentType::Image(fmt) => match fmt.as_str() {
40                "png" => "image/png",
41                "jpeg" | "jpg" => "image/jpeg",
42                "gif" => "image/gif",
43                "bmp" => "image/bmp",
44                "tiff" => "image/tiff",
45                "svg" => "image/svg+xml",
46                _ => "application/octet-stream",
47            },
48            ContentType::Media(fmt) => match fmt.as_str() {
49                "mp4" => "video/mp4",
50                "webm" => "video/webm",
51                "avi" => "video/x-msvideo",
52                "wmv" => "video/x-ms-wmv",
53                "mov" => "video/quicktime",
54                "mp3" => "audio/mpeg",
55                "wav" => "audio/wav",
56                "wma" => "audio/x-ms-wma",
57                "m4a" => "audio/mp4",
58                "ogg" => "audio/ogg",
59                _ => "application/octet-stream",
60            },
61            ContentType::Chart => "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
62            ContentType::Table => "application/vnd.openxmlformats-officedocument.drawingml.table+xml",
63            ContentType::CoreProperties => "application/vnd.openxmlformats-package.core-properties+xml",
64            ContentType::ExtendedProperties => "application/vnd.openxmlformats-officedocument.extended-properties+xml",
65            ContentType::ContentTypes => "application/vnd.openxmlformats-package.content-types+xml",
66            ContentType::Relationships => "application/vnd.openxmlformats-package.relationships+xml",
67            ContentType::Xml => "application/xml",
68        }
69    }
70}
71
72/// Part types in a PPTX package
73#[derive(Debug, Clone, Copy, PartialEq)]
74pub enum PartType {
75    Presentation,
76    Slide,
77    SlideLayout,
78    SlideMaster,
79    Theme,
80    NotesSlide,
81    NotesMaster,
82    Image,
83    Media,
84    Chart,
85    Table,
86    CoreProperties,
87    ExtendedProperties,
88    ContentTypes,
89    Relationships,
90}
91
92impl PartType {
93    /// Get the relationship type URI
94    pub fn relationship_type(&self) -> &'static str {
95        match self {
96            PartType::Presentation => "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
97            PartType::Slide => "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide",
98            PartType::SlideLayout => "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout",
99            PartType::SlideMaster => "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster",
100            PartType::Theme => "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",
101            PartType::NotesSlide => "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide",
102            PartType::NotesMaster => "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster",
103            PartType::Image => "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
104            PartType::Media => "http://schemas.openxmlformats.org/officeDocument/2006/relationships/media",
105            PartType::Chart => "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
106            PartType::Table => "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table",
107            PartType::CoreProperties => "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties",
108            PartType::ExtendedProperties => "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties",
109            PartType::ContentTypes => "http://schemas.openxmlformats.org/package/2006/content-types",
110            PartType::Relationships => "http://schemas.openxmlformats.org/package/2006/relationships",
111        }
112    }
113}
114
115/// Trait for package parts
116pub trait Part {
117    /// Get the part path within the package
118    fn path(&self) -> &str;
119    
120    /// Get the part type
121    fn part_type(&self) -> PartType;
122    
123    /// Get the content type
124    fn content_type(&self) -> ContentType;
125    
126    /// Generate XML content for this part
127    fn to_xml(&self) -> Result<String, PptxError>;
128    
129    /// Parse XML content into this part
130    fn from_xml(xml: &str) -> Result<Self, PptxError> where Self: Sized;
131}
132
133#[cfg(test)]
134mod tests {
135    use super::*;
136
137    #[test]
138    fn test_content_type_mime() {
139        assert_eq!(ContentType::Slide.mime_type(), 
140            "application/vnd.openxmlformats-officedocument.presentationml.slide+xml");
141        assert_eq!(ContentType::Image("png".to_string()).mime_type(), "image/png");
142        assert_eq!(ContentType::Image("jpeg".to_string()).mime_type(), "image/jpeg");
143    }
144
145    #[test]
146    fn test_part_type_relationship() {
147        assert!(PartType::Slide.relationship_type().contains("/slide"));
148        assert!(PartType::Image.relationship_type().contains("/image"));
149    }
150}