ckb_rocksdb/ops/
property.rs1use crate::{handle::Handle, ColumnFamily, Error};
2use libc::{c_char, c_void};
3use std::ffi::{CStr, CString};
4
5pub trait GetProperty {
6 fn property_value(&self, name: &str) -> Result<Option<String>, Error>;
11
12 fn property_int_value(&self, name: &str) -> Result<Option<u64>, Error>;
17}
18
19pub trait GetPropertyCF {
20 fn property_value_cf(&self, cf: &ColumnFamily, name: &str) -> Result<Option<String>, Error>;
25
26 fn property_int_value_cf(&self, cf: &ColumnFamily, name: &str) -> Result<Option<u64>, Error>;
31}
32
33impl<T> GetProperty for T
34where
35 T: Handle<ffi::rocksdb_t>,
36{
37 fn property_value(&self, name: &str) -> Result<Option<String>, Error> {
38 property_value_impl(
39 name,
40 |prop_name| unsafe { ffi::rocksdb_property_value(self.handle(), prop_name) },
41 |str_value| Ok(str_value.to_owned()),
42 )
43 }
44
45 fn property_int_value(&self, name: &str) -> Result<Option<u64>, Error> {
46 property_value_impl(
47 name,
48 |prop_name| unsafe { ffi::rocksdb_property_value(self.handle(), prop_name) },
49 parse_property_int_value,
50 )
51 }
52}
53
54impl<T> GetPropertyCF for T
55where
56 T: Handle<ffi::rocksdb_t>,
57{
58 fn property_value_cf(&self, cf: &ColumnFamily, name: &str) -> Result<Option<String>, Error> {
59 property_value_impl(
60 name,
61 |prop_name| unsafe {
62 ffi::rocksdb_property_value_cf(self.handle(), cf.inner, prop_name)
63 },
64 |str_value| Ok(str_value.to_owned()),
65 )
66 }
67
68 fn property_int_value_cf(&self, cf: &ColumnFamily, name: &str) -> Result<Option<u64>, Error> {
69 property_value_impl(
70 name,
71 |prop_name| unsafe {
72 ffi::rocksdb_property_value_cf(self.handle(), cf.inner, prop_name)
73 },
74 parse_property_int_value,
75 )
76 }
77}
78
79fn parse_property_int_value(value: &str) -> Result<u64, Error> {
80 value.parse::<u64>().map_err(|err| {
81 Error::new(format!(
82 "Failed to convert property value {} to int: {}",
83 value, err
84 ))
85 })
86}
87
88fn property_value_impl<R>(
97 name: &str,
98 get_property: impl FnOnce(*const c_char) -> *mut c_char,
99 parse: impl FnOnce(&str) -> Result<R, Error>,
100) -> Result<Option<R>, Error> {
101 let value = match CString::new(name) {
102 Ok(prop_name) => get_property(prop_name.as_ptr()),
103 Err(e) => {
104 return Err(Error::new(format!(
105 "Failed to convert property name to CString: {}",
106 e
107 )));
108 }
109 };
110 if value.is_null() {
111 return Ok(None);
112 }
113 let result = match unsafe { CStr::from_ptr(value) }.to_str() {
114 Ok(s) => parse(s).map(Some),
115 Err(e) => Err(Error::new(format!(
116 "Failed to convert property value to string: {}",
117 e
118 ))),
119 };
120 unsafe {
121 ffi::rocksdb_free(value as *mut c_void);
122 }
123 result
124}