mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Update config & dbus parts, cleanup deps, device power states
- Add extra config options and dbus methods - Add power state signals for anime and led - Refactor to use channels for dbus signal handler send/recv - Split out profiles independant parts to a rog-profiles crate - Cleanup dependencies - Fix some dbus Supported issues
This commit is contained in:
@@ -10,9 +10,11 @@ pub mod zbus_profile;
|
||||
pub mod zbus_rogbios;
|
||||
pub mod zbus_supported;
|
||||
|
||||
use rog_aura::AuraEffect;
|
||||
use rog_anime::AnimePowerStates;
|
||||
use rog_aura::{AuraEffect, LedPowerStates};
|
||||
use rog_profiles::profiles::Profile;
|
||||
use rog_types::gfx_vendors::{GfxRequiredUserAction, GfxVendors};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::mpsc::{channel, Receiver};
|
||||
use zbus::{Connection, Result, SignalReceiver};
|
||||
|
||||
pub static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
@@ -45,9 +47,9 @@ impl<'a> DbusProxies<'a> {
|
||||
))
|
||||
}
|
||||
|
||||
pub fn setup_recv(&'a self, conn: Connection) -> SignalReceiver {
|
||||
pub fn setup_recv(&'a self, conn: Connection) -> SignalReceiver<'a, 'a> {
|
||||
let mut recv = SignalReceiver::new(conn);
|
||||
//recv.receive_for(&self.proxy_anime);
|
||||
recv.receive_for(self.anime.proxy());
|
||||
recv.receive_for(self.led.proxy());
|
||||
recv.receive_for(self.charge.proxy());
|
||||
recv.receive_for(self.gfx.proxy());
|
||||
@@ -86,68 +88,91 @@ impl<'a> DbusProxies<'a> {
|
||||
|
||||
// Signals separated out
|
||||
pub struct Signals {
|
||||
pub gfx_vendor: Arc<Mutex<Option<GfxVendors>>>,
|
||||
pub gfx_action: Arc<Mutex<Option<GfxRequiredUserAction>>>,
|
||||
pub profile: Arc<Mutex<Option<String>>>,
|
||||
pub led_mode: Arc<Mutex<Option<AuraEffect>>>,
|
||||
pub charge: Arc<Mutex<Option<u8>>>,
|
||||
pub gfx_vendor: Receiver<GfxVendors>,
|
||||
pub gfx_action: Receiver<GfxRequiredUserAction>,
|
||||
pub profile: Receiver<Profile>,
|
||||
pub led_mode: Receiver<AuraEffect>,
|
||||
pub led_power_state: Receiver<LedPowerStates>,
|
||||
pub anime_power_state: Receiver<AnimePowerStates>,
|
||||
pub charge: Receiver<u8>,
|
||||
}
|
||||
|
||||
impl Signals {
|
||||
#[inline]
|
||||
pub fn new(proxies: &DbusProxies) -> Result<Self> {
|
||||
//
|
||||
let charge_signal = Arc::new(Mutex::new(None));
|
||||
proxies
|
||||
.charge
|
||||
.connect_notify_charge(charge_signal.clone())?;
|
||||
|
||||
//
|
||||
let ledmode_signal = Arc::new(Mutex::new(None));
|
||||
proxies.led.connect_notify_led(ledmode_signal.clone())?;
|
||||
|
||||
let gfx_action_signal = Arc::new(Mutex::new(None));
|
||||
proxies
|
||||
.gfx
|
||||
.connect_notify_action(gfx_action_signal.clone())?;
|
||||
|
||||
let gfx_vendor_signal = Arc::new(Mutex::new(None));
|
||||
proxies.gfx.connect_notify_gfx(gfx_vendor_signal.clone())?;
|
||||
|
||||
let profile_signal = Arc::new(Mutex::new(None));
|
||||
proxies
|
||||
.profile
|
||||
.connect_notify_profile(profile_signal.clone())?;
|
||||
|
||||
Ok(Signals {
|
||||
gfx_vendor: gfx_vendor_signal,
|
||||
gfx_action: gfx_action_signal,
|
||||
profile: profile_signal,
|
||||
led_mode: ledmode_signal,
|
||||
charge: charge_signal,
|
||||
gfx_vendor: {
|
||||
let (tx, rx) = channel();
|
||||
proxies.gfx.connect_notify_gfx(tx)?;
|
||||
rx
|
||||
},
|
||||
gfx_action: {
|
||||
let (tx, rx) = channel();
|
||||
proxies.gfx.connect_notify_action(tx)?;
|
||||
rx
|
||||
},
|
||||
profile: {
|
||||
let (tx, rx) = channel();
|
||||
proxies.profile.connect_notify_profile(tx)?;
|
||||
rx
|
||||
},
|
||||
charge: {
|
||||
let (tx, rx) = channel();
|
||||
proxies.charge.connect_notify_charge(tx)?;
|
||||
rx
|
||||
},
|
||||
led_mode: {
|
||||
let (tx, rx) = channel();
|
||||
proxies.led.connect_notify_led(tx)?;
|
||||
rx
|
||||
},
|
||||
led_power_state: {
|
||||
let (tx, rx) = channel();
|
||||
proxies.led.connect_notify_power_states(tx)?;
|
||||
rx
|
||||
},
|
||||
anime_power_state: {
|
||||
let (tx, rx) = channel();
|
||||
proxies.anime.connect_notify_power_states(tx)?;
|
||||
rx
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// This is the main way to communicate with the DBUS interface
|
||||
pub struct AuraDbusClient<'a> {
|
||||
pub struct RogDbusClient<'a> {
|
||||
proxies: DbusProxies<'a>,
|
||||
signals: Signals,
|
||||
}
|
||||
|
||||
impl<'a> AuraDbusClient<'a> {
|
||||
impl<'a> RogDbusClient<'a> {
|
||||
#[inline]
|
||||
pub fn new() -> Result<(Self, Connection)> {
|
||||
let (proxies, conn) = DbusProxies::new()?;
|
||||
let signals = Signals::new(&proxies)?;
|
||||
|
||||
Ok((AuraDbusClient { proxies, signals }, conn))
|
||||
Ok((RogDbusClient { proxies, signals }, conn))
|
||||
}
|
||||
|
||||
pub fn proxies(&self) -> &DbusProxies {
|
||||
&self.proxies
|
||||
}
|
||||
|
||||
pub fn signals(&self) -> &Signals {
|
||||
&self.signals
|
||||
}
|
||||
|
||||
pub fn setup_recv(&'a self, conn: Connection) -> SignalReceiver<'a, 'a> {
|
||||
let mut recv = SignalReceiver::new(conn);
|
||||
recv.receive_for(self.proxies.anime.proxy());
|
||||
recv.receive_for(self.proxies.led.proxy());
|
||||
recv.receive_for(self.proxies.charge.proxy());
|
||||
recv.receive_for(self.proxies.gfx.proxy());
|
||||
recv.receive_for(self.proxies.profile.proxy());
|
||||
recv
|
||||
}
|
||||
|
||||
/*
|
||||
* GFX
|
||||
*/
|
||||
@@ -155,10 +180,8 @@ impl<'a> AuraDbusClient<'a> {
|
||||
loop {
|
||||
if let Ok(res) = self.proxies.gfx.proxy().next_signal() {
|
||||
if res.is_none() {
|
||||
if let Ok(lock) = self.signals.gfx_action.lock() {
|
||||
if let Some(stuff) = lock.as_ref() {
|
||||
return Ok(*stuff);
|
||||
}
|
||||
if let Ok(stuff) = self.signals.gfx_action.try_recv() {
|
||||
return Ok(stuff);
|
||||
}
|
||||
// return Ok("Failed for unknown reason".to_owned());
|
||||
}
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
//!
|
||||
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
||||
|
||||
use rog_anime::AnimeDataBuffer;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
use rog_anime::{AnimeDataBuffer, AnimePowerStates};
|
||||
use zbus::{dbus_proxy, Connection, Result};
|
||||
|
||||
#[dbus_proxy(
|
||||
@@ -35,6 +37,15 @@ trait Daemon {
|
||||
|
||||
/// WriteDirect method
|
||||
fn write(&self, input: &[u8]) -> zbus::Result<()>;
|
||||
|
||||
#[dbus_proxy(property)]
|
||||
fn awake_enabled(&self) -> zbus::Result<bool>;
|
||||
|
||||
#[dbus_proxy(property)]
|
||||
fn boot_enabled(&self) -> zbus::Result<bool>;
|
||||
|
||||
#[dbus_proxy(signal)]
|
||||
fn notify_power_states(&self, data: AnimePowerStates) -> zbus::Result<()>;
|
||||
}
|
||||
|
||||
pub struct AnimeProxy<'a>(DaemonProxy<'a>);
|
||||
@@ -63,4 +74,26 @@ impl<'a> AnimeProxy<'a> {
|
||||
pub fn write(&self, input: AnimeDataBuffer) -> Result<()> {
|
||||
self.0.write(input.get())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn awake_enabled(&self) -> Result<bool> {
|
||||
self.0.awake_enabled()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn boot_enabled(&self) -> Result<bool> {
|
||||
self.0.boot_enabled()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn connect_notify_power_states(
|
||||
&self,
|
||||
send: Sender<AnimePowerStates>,
|
||||
) -> zbus::fdo::Result<()> {
|
||||
self.0.connect_notify_power_states(move |data| {
|
||||
send.send(data)
|
||||
.map_err(|err| zbus::fdo::Error::Failed(err.to_string()))?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
//!
|
||||
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
use zbus::{dbus_proxy, Connection, Result};
|
||||
|
||||
@@ -62,11 +62,10 @@ impl<'a> ChargeProxy<'a> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn connect_notify_charge(&self, charge: Arc<Mutex<Option<u8>>>) -> zbus::fdo::Result<()> {
|
||||
pub fn connect_notify_charge(&self, send: Sender<u8>) -> zbus::fdo::Result<()> {
|
||||
self.0.connect_notify_charge(move |data| {
|
||||
if let Ok(mut lock) = charge.lock() {
|
||||
*lock = Some(data);
|
||||
}
|
||||
send.send(data)
|
||||
.map_err(|err| zbus::fdo::Error::Failed(err.to_string()))?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
//!
|
||||
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
use rog_types::gfx_vendors::{GfxPower, GfxRequiredUserAction, GfxVendors};
|
||||
use zbus::{dbus_proxy, Connection, Result};
|
||||
@@ -77,25 +77,20 @@ impl<'a> GfxProxy<'a> {
|
||||
#[inline]
|
||||
pub fn connect_notify_action(
|
||||
&self,
|
||||
action: Arc<Mutex<Option<GfxRequiredUserAction>>>,
|
||||
send: Sender<GfxRequiredUserAction>,
|
||||
) -> zbus::fdo::Result<()> {
|
||||
self.0.connect_notify_action(move |data| {
|
||||
if let Ok(mut lock) = action.lock() {
|
||||
*lock = Some(data);
|
||||
}
|
||||
send.send(data)
|
||||
.map_err(|err| zbus::fdo::Error::Failed(err.to_string()))?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn connect_notify_gfx(
|
||||
&self,
|
||||
vendor: Arc<Mutex<Option<GfxVendors>>>,
|
||||
) -> zbus::fdo::Result<()> {
|
||||
pub fn connect_notify_gfx(&self, send: Sender<GfxVendors>) -> zbus::fdo::Result<()> {
|
||||
self.0.connect_notify_gfx(move |data| {
|
||||
if let Ok(mut lock) = vendor.lock() {
|
||||
*lock = Some(data);
|
||||
}
|
||||
send.send(data)
|
||||
.map_err(|err| zbus::fdo::Error::Failed(err.to_string()))?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
//!
|
||||
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
use zbus::{dbus_proxy, Connection, Result};
|
||||
|
||||
use rog_aura::{AuraEffect, KeyColourArray, LedBrightness};
|
||||
use rog_aura::{AuraEffect, KeyColourArray, LedBrightness, LedPowerStates};
|
||||
|
||||
const BLOCKING_TIME: u64 = 40; // 100ms = 10 FPS, max 50ms = 20 FPS, 40ms = 25 FPS
|
||||
|
||||
@@ -52,7 +52,10 @@ trait Daemon {
|
||||
|
||||
/// NotifyLed signal
|
||||
#[dbus_proxy(signal)]
|
||||
fn notify_led(&self, data: &str) -> zbus::Result<()>;
|
||||
fn notify_led(&self, data: AuraEffect) -> zbus::Result<()>;
|
||||
|
||||
#[dbus_proxy(signal)]
|
||||
fn notify_power_states(&self, data: LedPowerStates) -> zbus::Result<()>;
|
||||
|
||||
/// LedBrightness property
|
||||
#[dbus_proxy(property)]
|
||||
@@ -65,6 +68,12 @@ trait Daemon {
|
||||
/// LedModes property
|
||||
#[dbus_proxy(property)]
|
||||
fn led_modes(&self) -> zbus::Result<String>;
|
||||
|
||||
#[dbus_proxy(property)]
|
||||
fn awake_enabled(&self) -> zbus::Result<bool>;
|
||||
|
||||
#[dbus_proxy(property)]
|
||||
fn sleep_enabled(&self) -> zbus::Result<bool>;
|
||||
}
|
||||
|
||||
pub struct LedProxy<'a>(DaemonProxy<'a>);
|
||||
@@ -119,6 +128,16 @@ impl<'a> LedProxy<'a> {
|
||||
self.0.set_led_mode(mode)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn awake_enabled(&self) -> Result<bool> {
|
||||
self.0.awake_enabled()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn sleep_enabled(&self) -> Result<bool> {
|
||||
self.0.sleep_enabled()
|
||||
}
|
||||
|
||||
/// Write a single colour block.
|
||||
///
|
||||
/// Intentionally blocks for 10ms after sending to allow the block to
|
||||
@@ -152,13 +171,22 @@ impl<'a> LedProxy<'a> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn connect_notify_led(&self, led: Arc<Mutex<Option<AuraEffect>>>) -> zbus::fdo::Result<()> {
|
||||
pub fn connect_notify_led(&self, send: Sender<AuraEffect>) -> zbus::fdo::Result<()> {
|
||||
self.0.connect_notify_led(move |data| {
|
||||
if let Ok(mut lock) = led.lock() {
|
||||
if let Ok(dat) = serde_json::from_str(&data) {
|
||||
*lock = Some(dat);
|
||||
}
|
||||
}
|
||||
send.send(data)
|
||||
.map_err(|err| zbus::fdo::Error::Failed(err.to_string()))?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn connect_notify_power_states(
|
||||
&self,
|
||||
send: Sender<LedPowerStates>,
|
||||
) -> zbus::fdo::Result<()> {
|
||||
self.0.connect_notify_power_states(move |data| {
|
||||
send.send(data)
|
||||
.map_err(|err| zbus::fdo::Error::Failed(err.to_string()))?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
//!
|
||||
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
use rog_types::profile::ProfileEvent;
|
||||
use rog_profiles::profiles::Profile;
|
||||
use zbus::{dbus_proxy, Connection, Result};
|
||||
|
||||
#[dbus_proxy(
|
||||
@@ -29,14 +29,14 @@ use zbus::{dbus_proxy, Connection, Result};
|
||||
default_path = "/org/asuslinux/Profile"
|
||||
)]
|
||||
trait Daemon {
|
||||
/// ActiveProfileName method
|
||||
fn active_profile_name(&self) -> zbus::Result<String>;
|
||||
|
||||
/// NextProfile method
|
||||
fn next_profile(&self) -> zbus::Result<()>;
|
||||
|
||||
/// Profile, get the active profile
|
||||
fn profile(&self) -> zbus::Result<String>;
|
||||
fn active_name(&self) -> zbus::Result<String>;
|
||||
|
||||
/// Get the active `Profile` data
|
||||
fn active_data(&self) -> zbus::Result<Profile>;
|
||||
|
||||
/// Profiles method
|
||||
fn profiles(&self) -> zbus::Result<String>;
|
||||
@@ -48,26 +48,11 @@ trait Daemon {
|
||||
fn remove(&self, profile: &str) -> zbus::Result<()>;
|
||||
|
||||
/// SetProfile method
|
||||
fn set_profile(&self, profile: &str) -> zbus::Result<()>;
|
||||
|
||||
/// SetFanCurve method
|
||||
fn set_fan_curve(&self, curve: &str) -> zbus::Result<()>;
|
||||
|
||||
/// SetFanPreset method
|
||||
fn set_fan_preset(&self, preset: u8) -> zbus::Result<()>;
|
||||
|
||||
/// SetMaxFrequency method
|
||||
fn set_max_frequency(&self, percentage: u8) -> zbus::Result<()>;
|
||||
|
||||
/// SetMinFrequency method
|
||||
fn set_min_frequency(&self, percentage: u8) -> zbus::Result<()>;
|
||||
|
||||
/// SetTurbo method
|
||||
fn set_turbo(&self, enable: bool) -> zbus::Result<()>;
|
||||
fn new_or_modify(&self, profile: &Profile) -> zbus::Result<()>;
|
||||
|
||||
/// NotifyProfile signal
|
||||
#[dbus_proxy(signal)]
|
||||
fn notify_profile(&self, profile: &str) -> zbus::Result<()>;
|
||||
fn notify_profile(&self, profile: Profile) -> zbus::Result<()>;
|
||||
}
|
||||
|
||||
pub struct ProfileProxy<'a>(DaemonProxy<'a>);
|
||||
@@ -83,13 +68,13 @@ impl<'a> ProfileProxy<'a> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn active_profile_name(&self) -> Result<String> {
|
||||
self.0.active_profile_name()
|
||||
pub fn active_name(&self) -> Result<String> {
|
||||
self.0.active_name()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn active_profile_data(&self) -> Result<String> {
|
||||
self.0.profile()
|
||||
pub fn active_data(&self) -> Result<Profile> {
|
||||
self.0.active_data()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -102,49 +87,6 @@ impl<'a> ProfileProxy<'a> {
|
||||
self.0.next_profile()
|
||||
}
|
||||
|
||||
/// SetFanCurve, set fan curve for active profile
|
||||
#[inline]
|
||||
pub fn set_fan_curve(&self, curve: &str) -> zbus::Result<()> {
|
||||
self.0.set_fan_curve(curve)
|
||||
}
|
||||
|
||||
/// SetFanPreset, set fan preset for active profile
|
||||
#[inline]
|
||||
pub fn set_fan_preset(&self, preset: u8) -> zbus::Result<()> {
|
||||
self.0.set_fan_preset(preset)
|
||||
}
|
||||
|
||||
/// SetMaxFrequency, set max percentage of frequency for active profile
|
||||
#[inline]
|
||||
pub fn set_max_frequency(&self, percentage: u8) -> zbus::Result<()> {
|
||||
self.0.set_max_frequency(percentage)
|
||||
}
|
||||
|
||||
/// SetMinFrequency, set min percentage of frequency for active profile
|
||||
#[inline]
|
||||
pub fn set_min_frequency(&self, percentage: u8) -> zbus::Result<()> {
|
||||
self.0.set_min_frequency(percentage)
|
||||
}
|
||||
|
||||
/// SetTurbo, set turbo enable for active profile
|
||||
#[inline]
|
||||
pub fn set_turbo(&self, enable: bool) -> zbus::Result<()> {
|
||||
self.0.set_turbo(enable)
|
||||
}
|
||||
|
||||
// TODO: remove
|
||||
#[inline]
|
||||
pub fn write_fan_mode(&self, level: u8) -> Result<()> {
|
||||
self.0
|
||||
.set_profile(&serde_json::to_string(&ProfileEvent::ChangeMode(level)).unwrap())
|
||||
}
|
||||
|
||||
// TODO: remove
|
||||
#[inline]
|
||||
pub fn write_command(&self, cmd: &ProfileEvent) -> Result<()> {
|
||||
self.0.set_profile(&serde_json::to_string(cmd).unwrap())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn profile_names(&self) -> Result<Vec<String>> {
|
||||
self.0.profile_names()
|
||||
@@ -156,14 +98,15 @@ impl<'a> ProfileProxy<'a> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn connect_notify_profile(
|
||||
&self,
|
||||
charge: Arc<Mutex<Option<String>>>,
|
||||
) -> zbus::fdo::Result<()> {
|
||||
pub fn new_or_modify(&self, profile: &Profile) -> Result<()> {
|
||||
self.0.new_or_modify(profile)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn connect_notify_profile(&self, send: Sender<Profile>) -> zbus::fdo::Result<()> {
|
||||
self.0.connect_notify_profile(move |data| {
|
||||
if let Ok(mut lock) = charge.lock() {
|
||||
*lock = Some(data.to_owned());
|
||||
}
|
||||
send.send(data)
|
||||
.map_err(|err| zbus::fdo::Error::Failed(err.to_string()))?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
//!
|
||||
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
||||
|
||||
use rog_types::supported::SupportedFunctions;
|
||||
use zbus::{dbus_proxy, Connection, Result};
|
||||
|
||||
#[dbus_proxy(
|
||||
@@ -27,7 +28,7 @@ use zbus::{dbus_proxy, Connection, Result};
|
||||
)]
|
||||
trait Daemon {
|
||||
/// SupportedFunctions method
|
||||
fn supported_functions(&self) -> zbus::Result<String>;
|
||||
fn supported_functions(&self) -> zbus::Result<SupportedFunctions>;
|
||||
}
|
||||
|
||||
pub struct SupportProxy<'a>(DaemonProxy<'a>);
|
||||
@@ -43,7 +44,7 @@ impl<'a> SupportProxy<'a> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_supported_functions(&self) -> Result<String> {
|
||||
pub fn get_supported_functions(&self) -> Result<SupportedFunctions> {
|
||||
self.0.supported_functions()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user