1use crate::error::ZipErrorT;
2use crate::ffi;
3use crate::Error;
4use crate::Result;
5use std::ffi::{CStr, CString};
6use std::marker::PhantomData;
7use std::path::Path;
8use std::ptr::null_mut;
9
10pub enum File {}
12
13#[derive(Debug)]
15pub struct Source<'a> {
16 handle: *mut ffi::zip_source_t,
17 phantom: PhantomData<&'a ()>,
18}
19
20impl Source<'_> {
21 pub(crate) fn taken(mut self) {
24 self.handle = null_mut();
25 }
26
27 pub(crate) fn handle_mut(&mut self) -> *mut ffi::zip_source_t {
28 self.handle
29 }
30}
31
32impl<'a> TryFrom<&'a [u8]> for Source<'a> {
33 type Error = Error;
34
35 fn try_from(buffer: &[u8]) -> Result<Source<'_>> {
36 let mut error = ZipErrorT::default();
37 let handle = unsafe {
38 ffi::zip_source_buffer_create(buffer.as_ptr() as _, buffer.len() as _, 0, &mut *error)
39 };
40 if handle.is_null() {
41 Err(error.into())
42 } else {
43 Ok(Source {
44 handle,
45 phantom: PhantomData,
46 })
47 }
48 }
49}
50
51impl TryFrom<&CStr> for Source<'static> {
52 type Error = Error;
53
54 fn try_from(filename: &CStr) -> Result<Source<'static>> {
55 let mut error = ZipErrorT::default();
56 let handle = unsafe { ffi::zip_source_file_create(filename.as_ptr(), 0, 0, &mut *error) };
57 if handle.is_null() {
58 Err(error.into())
59 } else {
60 Ok(Source {
61 handle,
62 phantom: PhantomData,
63 })
64 }
65 }
66}
67
68impl TryFrom<&Path> for Source<'static> {
74 type Error = Error;
75
76 fn try_from(filename: &Path) -> Result<Source<'static>> {
77 let filename = CString::new(filename.to_string_lossy().into_owned())
78 .expect("The path could not be converted into a CString");
79 filename.as_ref().try_into()
80 }
81}
82
83impl Drop for Source<'_> {
84 fn drop(&mut self) {
85 if !self.handle.is_null() {
86 unsafe {
87 ffi::zip_source_free(self.handle);
88 }
89 }
90 }
91}