1use crate::{ok, sys, AsHandleRef, Handle, HandleBased, HandleRef, Status};
8
9#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
14#[repr(transparent)]
15pub struct Counter(Handle);
16impl_handle_based!(Counter);
17
18impl Counter {
19 pub fn create() -> Result<Counter, Status> {
20 let options = 0;
21 let mut handle = 0;
22 let status = unsafe { sys::zx_counter_create(options, &mut handle) };
23 ok(status)?;
24 unsafe { Ok(Counter::from(Handle::from_raw(handle))) }
25 }
26
27 pub fn add(&self, value: i64) -> Result<(), Status> {
28 let status = unsafe { sys::zx_counter_add(self.raw_handle(), value) };
29 ok(status)
30 }
31
32 pub fn read(&self) -> Result<i64, Status> {
33 let mut value = 0;
34 let status = unsafe { sys::zx_counter_read(self.raw_handle(), &mut value) };
35 ok(status).map(|()| value)
36 }
37
38 pub fn write(&self, value: i64) -> Result<(), Status> {
39 let status = unsafe { sys::zx_counter_write(self.raw_handle(), value) };
40 ok(status)
41 }
42}
43
44#[cfg(test)]
48mod tests {
49 use super::*;
50
51 #[test]
52 fn counter_create() {
53 let counter = Counter::create().unwrap();
54 assert_eq!(counter.read().unwrap(), 0);
55 }
56
57 #[test]
58 fn counter_add() {
59 let counter = Counter::create().unwrap();
60 assert_eq!(counter.read().unwrap(), 0);
61 assert!(counter.add(i64::max_value()).is_ok());
62 assert_eq!(counter.read().unwrap(), i64::max_value());
63 assert_eq!(counter.add(1), Err(Status::OUT_OF_RANGE));
64 }
65
66 #[test]
67 fn counter_read_write() {
68 let counter = Counter::create().unwrap();
69 assert_eq!(counter.read().unwrap(), 0);
70 assert!(counter.write(i64::min_value()).is_ok());
71 assert_eq!(counter.read().unwrap(), i64::min_value());
72 }
73}