]> git.sesse.net Git - bcachefs-tools-debian/blob - rust-src/bch_bindgen/src/lib.rs
rust: Fix ptr casting in Fs::open()
[bcachefs-tools-debian] / rust-src / bch_bindgen / src / lib.rs
1 pub mod bcachefs;
2 pub mod btree;
3 pub mod bkey;
4 pub mod errcode;
5 pub mod keyutils;
6 pub mod log;
7 pub mod rs;
8 pub mod fs;
9 pub mod opts;
10 pub use paste::paste;
11
12 pub mod c {
13     pub use crate::bcachefs::*;
14 }
15
16 use c::bpos as Bpos;
17
18 pub const fn spos(inode: u64, offset: u64, snapshot: u32) -> Bpos {
19     Bpos { inode, offset, snapshot }
20 }
21
22 pub const fn pos(inode: u64, offset: u64) -> Bpos {
23     spos(inode, offset, 0)
24 }
25
26 pub const POS_MIN:  Bpos = spos(0, 0, 0);
27 pub const POS_MAX:  Bpos = spos(u64::MAX, u64::MAX, 0);
28 pub const SPOS_MAX: Bpos = spos(u64::MAX, u64::MAX, u32::MAX);
29
30 use std::cmp::Ordering;
31
32 impl PartialEq for Bpos {
33     fn eq(&self, other: &Self) -> bool {
34         self.cmp(other) == Ordering::Equal
35     }
36 }
37
38 impl Eq for Bpos {}
39
40 impl PartialOrd for Bpos {
41     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
42         Some(self.cmp(other))
43     }
44 }
45
46 impl Ord for Bpos {
47     fn cmp(&self, other: &Self) -> Ordering {
48         let l_inode     = self.inode;
49         let r_inode     = other.inode;
50         let l_offset    = self.offset;
51         let r_offset    = other.offset;
52         let l_snapshot  = self.snapshot;
53         let r_snapshot  = other.snapshot;
54
55         l_inode.cmp(&r_inode)
56             .then(l_offset.cmp(&r_offset))
57             .then(l_snapshot.cmp(&r_snapshot))
58     }
59 }
60
61 use std::ffi::CStr;
62 use std::fmt;
63
64 impl fmt::Display for c::btree_id {
65     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
66         let s = unsafe { CStr::from_ptr(*c::bch2_btree_ids.get_unchecked(*self as usize)) };
67         let s = s.to_str().unwrap();
68         write!(f, "{}", s)
69     }
70 }
71
72 use std::str::FromStr;
73 use std::ffi::CString;
74
75 use std::error::Error;
76
77 #[derive(Debug)]
78 pub struct InvalidBtreeId;
79
80 impl fmt::Display for InvalidBtreeId {
81     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82         write!(f, "invalid btree id")
83     }
84 }
85
86 impl Error for InvalidBtreeId {
87 }
88
89 impl FromStr for c::btree_id {
90     type Err = InvalidBtreeId;
91
92     fn from_str(s: &str) -> Result<Self, Self::Err> {
93         let s = CString::new(s).unwrap();
94         let p = s.as_ptr();
95
96         let v = unsafe {c::match_string(c::bch2_btree_ids[..].as_ptr(), (-(1 as isize)) as usize, p)};
97         if v >= 0 {
98             Ok(unsafe { std::mem::transmute(v) })
99         } else {
100             Err(InvalidBtreeId)
101         }
102     }
103 }
104
105 impl c::printbuf {
106     fn new() -> c::printbuf {
107         let mut buf: c::printbuf = Default::default();
108
109         buf.set_heap_allocated(true);
110         buf
111     }
112 }
113
114 impl Drop for c::printbuf {
115     fn drop(&mut self) {
116         unsafe { c::bch2_printbuf_exit(self) }
117     }             
118 }
119
120 impl fmt::Display for Bpos {
121     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
122         let mut buf = c::printbuf::new();
123
124         unsafe { c::bch2_bpos_to_text(&mut buf, *self) };
125  
126         let s = unsafe { CStr::from_ptr(buf.buf) };
127         let s = s.to_str().unwrap();
128         write!(f, "{}", s)
129     }
130 }
131
132 impl FromStr for c::bpos {
133     type Err = InvalidBtreeId;
134
135     fn from_str(s: &str) -> Result<Self, Self::Err> {
136         if s == "POS_MIN" {
137             return Ok(POS_MIN);
138         }
139
140         if s == "POS_MAX" {
141             return Ok(POS_MAX);
142         }
143
144         if s == "SPOS_MAX" {
145             return Ok(SPOS_MAX);
146         }
147
148         let mut fields = s.split(':');
149         let ino_str = fields.next().ok_or(InvalidBtreeId)?;
150         let off_str = fields.next().ok_or(InvalidBtreeId)?;
151         let snp_str = fields.next();
152
153         let ino: u64    = ino_str.parse().map_err(|_| InvalidBtreeId)?;
154         let off: u64    = off_str.parse().map_err(|_| InvalidBtreeId)?;
155         let snp: u32    = snp_str.map(|s| s.parse().ok()).flatten().unwrap_or(0);
156
157         Ok(c::bpos { inode: ino, offset: off, snapshot: snp })
158     }
159 }