chore+feat(home-assistant): update to pyo3 0.27 and update extraction errors, switch out SmolStr for Arc<str>, tighten up light service calls and implement some for notify, start implementing units of measurement like for power
This commit is contained in:
223
home-assistant/src/notify/service/mobile_app/mod.rs
Normal file
223
home-assistant/src/notify/service/mobile_app/mod.rs
Normal file
@@ -0,0 +1,223 @@
|
||||
use std::{convert::Infallible, str::FromStr};
|
||||
|
||||
use pyo3::{types::PyString, Bound, IntoPyObject, Python};
|
||||
use python_utils::IntoPyObjectViaDisplay;
|
||||
use snafu::Snafu;
|
||||
use strum::EnumString;
|
||||
use url::Url;
|
||||
|
||||
pub mod command;
|
||||
pub mod standard;
|
||||
pub mod text_to_speech;
|
||||
|
||||
pub use command::*;
|
||||
pub use standard::StandardNotification;
|
||||
pub use text_to_speech::TextToSpeech;
|
||||
|
||||
#[derive(Debug, Clone, derive_more::Display)]
|
||||
pub struct NonSpecialMessage(String);
|
||||
|
||||
#[derive(Debug, Clone, EnumString, strum::Display)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum SpecialMessage {
|
||||
ClearBadge,
|
||||
ClearNotification,
|
||||
CommandActivity,
|
||||
CommandAppLock,
|
||||
CommandAutoScreenBrightness,
|
||||
CommandBluetooth,
|
||||
CommandBleTransmitter,
|
||||
CommandBeaconMonitor,
|
||||
CommandBroadcastIntent,
|
||||
CommandDnd,
|
||||
CommandFlashlight,
|
||||
CommandHighAccuracyMode,
|
||||
CommandLaunchApp,
|
||||
CommandMedia,
|
||||
CommandRingerMode,
|
||||
CommandScreenBrightnessLevel,
|
||||
CommandScreenOffTimeout,
|
||||
CommandScreenOn,
|
||||
CommandStopTts,
|
||||
CommandPersistentConnection,
|
||||
CommandUpdateSensors,
|
||||
CommandVolumeLevel,
|
||||
CommandWebivew,
|
||||
RemoveChannel,
|
||||
RequestLocationUpdate,
|
||||
// #[strum(serialize = "TTS")] TODO: WIP: TESTING
|
||||
Tts,
|
||||
UpdateComplications,
|
||||
UpdateWidgets,
|
||||
}
|
||||
|
||||
/// wasn't supposed to get a specially-behaving message here, but got {got}
|
||||
#[derive(Debug, Clone, Snafu)]
|
||||
pub struct WasSpecialMessage {
|
||||
pub got: SpecialMessage,
|
||||
}
|
||||
|
||||
impl FromStr for NonSpecialMessage {
|
||||
type Err = WasSpecialMessage;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match SpecialMessage::from_str(s) {
|
||||
Ok(special_message) => Err(WasSpecialMessage {
|
||||
got: special_message,
|
||||
}),
|
||||
Err(_e) => Ok(NonSpecialMessage(s.into())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// How much of a notification is visible on the lock screen
|
||||
#[derive(Debug, Clone, Default, EnumString, strum::Display)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum Visibility {
|
||||
/// always show all notification content
|
||||
Public,
|
||||
/// visibility depends on your setting in the system Settings app > Notifications;
|
||||
/// if the option to show sensitive notifications when locked is enabled all notification content will be shown,
|
||||
/// otherwise only basic information such as the icon and app name are visible
|
||||
#[default]
|
||||
Private,
|
||||
/// always hide notification from lock screen
|
||||
Secret,
|
||||
}
|
||||
|
||||
// TODO: replace with a derive(DisplayToPy) (analogous to serde_with::SerializeDisplay) once I make one
|
||||
impl<'py> IntoPyObject<'py> for Visibility {
|
||||
type Target = PyString;
|
||||
type Output = Bound<'py, Self::Target>;
|
||||
type Error = Infallible;
|
||||
|
||||
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
|
||||
let s = self.to_string();
|
||||
s.into_pyobject(py)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, EnumString, strum::Display)]
|
||||
pub enum Behavior {
|
||||
/// prompt for text to return with the event
|
||||
#[strum(serialize = "textInput")]
|
||||
TextInput,
|
||||
}
|
||||
|
||||
// TODO: replace with a derive(DisplayToPy) (analogous to serde_with::SerializeDisplay) once I make one
|
||||
impl<'py> IntoPyObject<'py> for Behavior {
|
||||
type Target = PyString;
|
||||
type Output = Bound<'py, Self::Target>;
|
||||
type Error = Infallible;
|
||||
|
||||
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
|
||||
let s = self.to_string();
|
||||
s.into_pyobject(py)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, EnumString, strum::Display)]
|
||||
#[strum(serialize_all = "camelCase")]
|
||||
pub enum ActivationMode {
|
||||
/// launch the app when tapped
|
||||
Foreground,
|
||||
/// just fires the event
|
||||
#[default]
|
||||
Background,
|
||||
}
|
||||
|
||||
// TODO: replace with a derive(DisplayToPy) (analogous to serde_with::SerializeDisplay) once I make one
|
||||
impl<'py> IntoPyObject<'py> for ActivationMode {
|
||||
type Target = PyString;
|
||||
type Output = Bound<'py, Self::Target>;
|
||||
type Error = Infallible;
|
||||
|
||||
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
|
||||
let s = self.to_string();
|
||||
s.into_pyobject(py)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: better typed versions like `CallNumber` or `OpenWebpage` where Action: From<CallNumber> and Action: From<OpenWebPage>
|
||||
#[derive(Debug, Clone, IntoPyObject, typed_builder::TypedBuilder)]
|
||||
#[builder(field_defaults(default, setter(strip_option(fallback_suffix = "_option"))))]
|
||||
pub struct Action {
|
||||
// TODO: proper type
|
||||
// TODO: I wish I could call this identifier or something instead
|
||||
#[builder(!default, setter(!strip_option))]
|
||||
pub action: String,
|
||||
#[builder(!default, setter(!strip_option))]
|
||||
pub title: String,
|
||||
|
||||
pub uri: Option<IntoPyObjectViaDisplay<Url>>,
|
||||
pub behavior: Option<Behavior>,
|
||||
|
||||
// TODO: make this written as activationMode
|
||||
/// (iOS only) decide whether to open the app (to the foreground) when tapped
|
||||
/// or merely fire an event (in the background)
|
||||
pub activation_mode: Option<ActivationMode>,
|
||||
|
||||
// TODO: make this written as authenticationRequired
|
||||
/// (iOS only) require entering a passcode to use the action
|
||||
pub authentication_required: Option<bool>,
|
||||
|
||||
/// (iOS only) color the action's title red, indicating a destructive action
|
||||
pub destructive: Option<bool>,
|
||||
|
||||
// TODO: make this written as textInputButtonTitle
|
||||
/// (iOS only) Title to use for text input for actions that prompt
|
||||
pub text_input_button_title: Option<String>,
|
||||
|
||||
// TODO: make this written as textInputPlaceholder
|
||||
/// (iOS only) Placeholder to use for text input for actions that prompt
|
||||
pub text_input_placeholder: Option<String>,
|
||||
|
||||
// TODO: proper type
|
||||
/// (iOS only) icon to use for the notification
|
||||
pub icon: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, EnumString, strum::Display)]
|
||||
#[strum(serialize_all = "snake_case", suffix = "_stream")]
|
||||
pub enum MediaStream {
|
||||
Alarm,
|
||||
Call,
|
||||
Dtmf,
|
||||
#[default]
|
||||
Music,
|
||||
Notification,
|
||||
Ring,
|
||||
System,
|
||||
}
|
||||
|
||||
// TODO: replace with a derive(DisplayToPy) (analogous to serde_with::SerializeDisplay) once I make one
|
||||
impl<'py> IntoPyObject<'py> for MediaStream {
|
||||
type Target = PyString;
|
||||
type Output = Bound<'py, Self::Target>;
|
||||
type Error = Infallible;
|
||||
|
||||
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
|
||||
let s = self.to_string();
|
||||
s.into_pyobject(py)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, IntoPyObject, typed_builder::TypedBuilder)]
|
||||
#[builder(field_defaults(default, setter(strip_option(fallback_suffix = "_option"))))]
|
||||
pub struct NotifyMobileAppServiceDataData {
|
||||
actions: Option<Vec<Action>>,
|
||||
media_stream: Option<MediaStream>,
|
||||
tts_text: Option<String>,
|
||||
visibility: Option<Visibility>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, IntoPyObject, typed_builder::TypedBuilder)]
|
||||
#[builder(field_defaults(default, setter(strip_option(fallback_suffix = "_option"))))]
|
||||
pub struct NotifyMobileAppServiceData {
|
||||
#[builder(!default, setter(!strip_option))]
|
||||
message: String,
|
||||
|
||||
title: Option<String>,
|
||||
#[builder(setter(!strip_option))]
|
||||
data: NotifyMobileAppServiceDataData,
|
||||
}
|
||||
Reference in New Issue
Block a user