]> uap-core.de Git - note.git/commitdiff
add dav resource methods for accessing children
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 21 Jun 2026 17:57:45 +0000 (19:57 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 21 Jun 2026 17:57:45 +0000 (19:57 +0200)
dav-rs/src/dav/resource.rs

index 9f58871f66176aff5b5ea329c3e1a784aaca48fe..07cdcf96e6589c764963413406de60cc6a0d3ad1 100644 (file)
 #![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,
+                }
             }
         }
     }
@@ -83,4 +166,7 @@ unsafe extern "C" {
     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