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