#![allow(dead_code)]
use std::ffi::{c_char, c_int, CString};
+use std::marker::PhantomData;
+use std::ops::Deref;
use crate::dav::context::DavContext;
use crate::dav::ffi;
use crate::dav::session::Session;
-pub struct Resource {
- pub ptr: *mut ffi::DavResource,
+pub struct Resource<'a> {
+ base: ResourceRef<'a>
}
-impl Drop for Resource {
+pub struct ResourceRef<'a> {
+ ptr: *mut ffi::DavResource,
+ _marker: PhantomData<&'a Resource<'a>>,
+}
+
+impl<'a> Drop for Resource<'a> {
fn drop(&mut self) {
unsafe {
- dav_resource_free_all(self.ptr);
+ dav_resource_free_all(self.base.ptr);
}
}
}
-impl Resource {
- pub fn create(&self) -> bool {
- unsafe {
- dav_resource_create(self.ptr) != 0
+impl<'a> Deref for Resource<'a> {
+ type Target = ResourceRef<'a>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.base
+ }
+}
+
+
+impl<'a> ResourceRef<'a> {
+ fn resource_ref(&self, ptr: *mut ffi::DavResource) -> Option<ResourceRef<'_>> {
+ if ptr.is_null() {
+ return None;
}
+
+ Some(ResourceRef {
+ ptr: ptr,
+ _marker: PhantomData,
+ })
}
- pub fn delete(&self) -> bool {
- unsafe {
- dav_resource_delete(self.ptr) != 0
+ pub fn child(&self) -> Option<ResourceRef<'_>> {
+ unsafe { self.resource_ref((*self.ptr).children) }
+ }
+
+ pub fn prev(&self) -> Option<ResourceRef<'_>> {
+ unsafe { self.resource_ref((*self.ptr).prev) }
+ }
+
+ pub fn next(&self) -> Option<ResourceRef<'_>> {
+ unsafe { self.resource_ref((*self.ptr).next) }
+ }
+
+ pub fn children(&self) -> Children<'_> {
+ Children {
+ current: unsafe { (*self.ptr).children },
+ _marker: PhantomData,
}
}
pub fn exists(&self) -> bool {
+ unsafe { dav_resource_exists(self.ptr) != 0 }
+ }
+
+ pub fn create(&self) -> bool {
+ unsafe { dav_resource_create(self.ptr) == 0 }
+ }
+
+ pub fn delete(&self) -> bool {
+ unsafe { dav_resource_delete(self.ptr) == 0 }
+ }
+
+ pub fn load(&self) -> bool {
+ unsafe { dav_load(self.ptr) == 0 }
+ }
+
+ pub fn store(&self) -> bool {
+ unsafe { dav_store(self.ptr) == 0 }
+ }
+
+ pub fn as_ptr(&self) -> *mut ffi::DavResource {
+ self.ptr
+ }
+}
+
+
+pub struct Children<'a> {
+ current: *mut ffi::DavResource,
+ _marker: PhantomData<&'a Resource<'a>>,
+}
+
+impl<'a> Iterator for Children<'a> {
+ type Item = ResourceRef<'a>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let current = self.current;
+
+ if current.is_null() {
+ return None;
+ }
+
unsafe {
- dav_resource_exists(self.ptr) != 0
+ self.current = (*current).next;
}
+
+ Some(ResourceRef {
+ ptr: current,
+ _marker: PhantomData,
+ })
}
}
+
impl Session {
- pub fn new_resource(&self, path: &str) -> Resource {
+ pub fn new_resource<'a>(&self, path: &str) -> Resource<'a> {
let cstr = CString::new(path).unwrap();
unsafe {
Resource {
- ptr: dav_resource_new(self.ptr, cstr.as_ptr())
+ base: ResourceRef {
+ ptr: dav_resource_new(self.ptr, cstr.as_ptr()),
+ _marker: PhantomData,
+ }
}
}
}
fn dav_resource_create(res: *mut ffi::DavResource) -> c_int;
fn dav_resource_delete(res: *mut ffi::DavResource) -> c_int;
fn dav_resource_exists(res: *mut ffi::DavResource) -> c_int;
+
+ fn dav_load(res: *mut ffi::DavResource) -> c_int;
+ fn dav_store(res: *mut ffi::DavResource) -> c_int;
}
\ No newline at end of file