use super::platform;
use core::fmt;
use dioxus::prelude::Coroutine;
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct Geocoordinates {
pub latitude: f64,
pub longitude: f64,
}
#[derive(Debug)]
pub enum PowerMode {
High,
Low,
}
#[derive(Debug)]
pub enum Event {
StatusChanged(Status),
NewGeocoordinates(Geocoordinates),
}
#[derive(Debug)]
pub enum Access {
Allowed,
Denied,
Unspecified,
}
#[derive(Debug, PartialEq)]
pub enum Status {
Ready,
Disabled,
NotAvailable,
Initializing,
Unknown,
}
pub struct Geolocator {
device_geolocator: platform::Geolocator,
}
impl Geolocator {
pub fn new(power_mode: PowerMode) -> Result<Self, Error> {
let mut device_geolocator = platform::Geolocator::new()?;
platform::set_power_mode(&mut device_geolocator, power_mode)?;
Ok(Self { device_geolocator })
}
pub async fn get_coordinates(&self) -> Result<Geocoordinates, Error> {
platform::get_coordinates(&self.device_geolocator).await
}
pub fn listen(&self, listener: Coroutine<Event>) -> Result<(), Error> {
let tx = listener.tx();
platform::listen(
&self.device_geolocator,
Arc::new(move |event: Event| {
tx.unbounded_send(event).ok();
}),
)
}
}
#[derive(Debug, Clone)]
pub enum Error {
NotInitialized,
AccessDenied,
Poisoned,
DeviceError(String),
Unsupported,
}
impl std::error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::NotInitialized => write!(f, "not initialized"),
Error::AccessDenied => {
write!(f, "access denied (access may have been revoked during use)")
}
Error::Poisoned => write!(f, "the internal read/write lock has been poisioned"),
Error::DeviceError(e) => write!(f, "a device error has occurred: {}", e),
Error::Unsupported => write!(f, "the current platform is not supported"),
}
}
}