pebble_skip/user_interface/
vibes.rs

1use core::marker::PhantomData;
2
3#[allow(clippy::wildcard_imports)]
4use pebble_sys::user_interface::vibes::{VibePattern as sysVibePattern, *};
5
6pub fn cancel() {
7	unsafe { vibes_cancel() }
8}
9
10pub fn short_pulse() {
11	unsafe { vibes_short_pulse() }
12}
13
14pub fn long_pulse() {
15	unsafe { vibes_long_pulse() }
16}
17
18pub fn double_pulse() {
19	unsafe { vibes_double_pulse() }
20}
21
22pub fn enqueue_custom_pattern(pattern: &VibePattern) {
23	unsafe { vibes_enqueue_custom_pattern(pattern.as_sys()) }
24}
25
26pub struct VibePattern<'a>(&'a [u32]);
27
28pub enum VibePatternError {
29	Empty,
30	TooManyDurations,
31	DurationTooLong { index: usize },
32}
33
34impl<'a> VibePattern<'a> {
35	/// # Errors
36	///
37	/// If durations is empty, contains an element larger than `10_000`ms or
38	/// its length doesn't fit 32 bit (but good luck allocating that on a Pebble 😉).
39	pub fn new(durations: &'a [u32]) -> Result<Self, VibePatternError> {
40		if durations.is_empty() {
41			return Err(VibePatternError::Empty);
42		}
43
44		if durations.len() > u32::MAX as usize {
45			return Err(VibePatternError::TooManyDurations);
46		}
47
48		for (index, duration) in durations.iter().enumerate() {
49			if *duration > 10_000 {
50				return Err(VibePatternError::DurationTooLong { index });
51			}
52		}
53
54		Ok(Self(durations))
55	}
56
57	#[must_use]
58	pub fn as_sys(&self) -> sysVibePattern<'a> {
59		#[allow(clippy::cast_possible_truncation)] // Checked in constructor.
60		sysVibePattern {
61			durations: self.0 as *const _ as *const u32,
62			num_segments: self.0.len() as u32,
63			phantom: PhantomData,
64		}
65	}
66}