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