11use crate :: device_file:: read;
2+ use crate :: ErrorBox ;
3+ use futures_util:: { FutureExt , StreamExt , TryFutureExt } ;
4+ use smol:: fs:: File ;
5+ use smol:: lock:: Mutex ;
26use std:: collections:: HashMap ;
3- use std:: error:: Error ;
4- use std:: fs;
5- use std:: fs:: File ;
7+ use std:: ops:: DerefMut ;
68use std:: path:: { Path , PathBuf } ;
7- use std:: sync:: Mutex ;
89use SensorType :: * ;
910
11+ #[ allow( clippy:: large_enum_variant) ]
1012enum SensorType {
1113 Illuminance {
1214 value : Mutex < File > ,
@@ -26,111 +28,129 @@ pub struct Als {
2628}
2729
2830impl Als {
29- pub fn new ( base_path : & str , thresholds : HashMap < u64 , String > ) -> Result < Self , Box < dyn Error > > {
30- Path :: new ( base_path)
31- . read_dir ( )
32- . ok ( )
33- . and_then ( |dir| {
34- dir. filter_map ( |e| e. ok ( ) )
35- . find ( |e| {
36- [ "als" , "acpi-als" , "apds9960" ] . contains (
37- & fs:: read_to_string ( e. path ( ) . join ( "name" ) )
38- . unwrap_or_default ( )
39- . trim ( ) ,
40- )
41- } )
42- . and_then ( |e| {
43- // TODO should probably start from the `parse_illuminance_input` in the next major version
44- parse_illuminance_raw ( e. path ( ) )
45- . or_else ( |_| parse_illuminance_input ( e. path ( ) ) )
46- . or_else ( |_| parse_intensity_raw ( e. path ( ) ) )
47- . or_else ( |_| parse_intensity_rgb ( e. path ( ) ) )
48- . ok ( )
31+ pub async fn new ( base_path : & str , thresholds : HashMap < u64 , String > ) -> Result < Self , ErrorBox > {
32+ smol:: fs:: read_dir ( base_path)
33+ . await
34+ . map_err ( |e| ErrorBox :: from ( format ! ( "Can't enumerate iio devices: {e}" ) ) ) ?
35+ . filter_map ( |r| async { r. ok ( ) } )
36+ . then ( |entry| {
37+ smol:: fs:: read_to_string ( entry. path ( ) . join ( "name" ) ) . map ( |name| ( name, entry) )
38+ } )
39+ . filter_map ( |( name, entry) | async {
40+ [ "als" , "acpi-als" , "apds9960" ]
41+ . contains ( & name. unwrap_or_default ( ) . trim ( ) )
42+ . then_some ( entry)
43+ } )
44+ . filter_map ( |entry| async move {
45+ // TODO should probably start from the `parse_illuminance_input` in the next major version
46+ parse_illuminance_raw ( entry. path ( ) )
47+ . or_else ( |_| parse_illuminance_input ( entry. path ( ) ) )
48+ . or_else ( |_| parse_intensity_raw ( entry. path ( ) ) )
49+ . or_else ( |_| parse_intensity_rgb ( entry. path ( ) ) )
50+ . await
51+ . map ( Some )
52+ . unwrap_or_else ( |_| {
53+ log:: error!( "Failed to read sensor '{}'" , entry. path( ) . display( ) ) ;
54+ None
4955 } )
5056 } )
57+ . boxed ( )
58+ . next ( )
59+ . await
5160 . map ( |sensor| Self { sensor, thresholds } )
52- . ok_or_else ( || "No iio device found" . into ( ) )
61+ . ok_or_else ( || ErrorBox :: from ( "No iio device found" ) )
62+ }
63+
64+ pub async fn get ( & self ) -> Result < String , ErrorBox > {
65+ let raw = self . get_raw ( ) . await ?;
66+ let profile = super :: find_profile ( raw, & self . thresholds ) ;
67+
68+ log:: trace!( "ALS (iio): {} ({})" , profile, raw) ;
69+ Ok ( profile)
5370 }
5471
55- fn get_raw ( & self ) -> Result < u64 , Box < dyn Error > > {
72+ async fn get_raw ( & self ) -> Result < u64 , ErrorBox > {
5673 Ok ( match self . sensor {
5774 Illuminance {
5875 ref value,
5976 scale,
6077 offset,
61- } => ( read ( & mut value. lock ( ) . unwrap ( ) ) ? + offset) * scale,
78+ } => ( read ( value. lock ( ) . await . deref_mut ( ) ) . await ? + offset) * scale,
6279
6380 Intensity {
6481 ref r,
6582 ref g,
6683 ref b,
6784 } => {
68- -0.32466 * read ( & mut r. lock ( ) . unwrap ( ) ) ?
69- + 1.57837 * read ( & mut g. lock ( ) . unwrap ( ) ) ?
70- + -0.73191 * read ( & mut b. lock ( ) . unwrap ( ) ) ?
85+ -0.32466 * read ( r. lock ( ) . await . deref_mut ( ) ) . await ?
86+ + 1.57837 * read ( g. lock ( ) . await . deref_mut ( ) ) . await ?
87+ + -0.73191 * read ( b. lock ( ) . await . deref_mut ( ) ) . await ?
7188 }
7289 } as u64 )
7390 }
7491}
7592
76- impl super :: Als for Als {
77- fn get ( & self ) -> Result < String , Box < dyn Error > > {
78- let raw = self . get_raw ( ) ?;
79- let profile = super :: find_profile ( raw, & self . thresholds ) ;
80-
81- log:: trace!( "ALS (iio): {} ({})" , profile, raw) ;
82- Ok ( profile)
83- }
84- }
85-
86- fn parse_illuminance_raw ( path : PathBuf ) -> Result < SensorType , Box < dyn Error > > {
93+ async fn parse_illuminance_raw ( path : PathBuf ) -> Result < SensorType , ErrorBox > {
8794 Ok ( Illuminance {
8895 value : Mutex :: new (
8996 open_file ( & path, "in_illuminance_raw" )
90- . or_else ( |_| open_file ( & path, "in_illuminance0_raw" ) ) ?,
97+ . or_else ( |_| open_file ( & path, "in_illuminance0_raw" ) )
98+ . await ?,
9199 ) ,
92- scale : open_file ( & path, "in_illuminance_scale" )
93- . or_else ( |_| open_file ( & path, "in_illuminance0_scale" ) )
94- . and_then ( |mut f| read ( & mut f) )
95- . unwrap_or ( 1_f64 ) ,
96- offset : open_file ( & path, "in_illuminance_offset" )
97- . or_else ( |_| open_file ( & path, "in_illuminance0_offset" ) )
98- . and_then ( |mut f| read ( & mut f) )
99- . unwrap_or ( 0_f64 ) ,
100+ scale : {
101+ open_file ( & path, "in_illuminance_scale" )
102+ . or_else ( |_| open_file ( & path, "in_illuminance0_scale" ) )
103+ . and_then ( move |mut f| async move { read ( & mut f) . await } )
104+ . await
105+ . unwrap_or ( 1_f64 )
106+ } ,
107+ offset : {
108+ open_file ( & path, "in_illuminance_offset" )
109+ . or_else ( |_| open_file ( & path, "in_illuminance0_offset" ) )
110+ . and_then ( move |mut f| async move { read ( & mut f) . await } )
111+ . await
112+ . unwrap_or ( 0_f64 )
113+ } ,
100114 } )
101115}
102116
103- fn parse_intensity_raw ( path : PathBuf ) -> Result < SensorType , Box < dyn Error > > {
117+ async fn parse_intensity_raw ( path : PathBuf ) -> Result < SensorType , ErrorBox > {
118+ async fn try_open_and_read ( path : & Path , name : & str ) -> Result < f64 , ErrorBox > {
119+ let mut f = open_file ( path, name) . await ?;
120+ read ( & mut f) . await
121+ }
122+
104123 Ok ( Illuminance {
105- value : Mutex :: new ( open_file ( & path, "in_intensity_both_raw" ) ?) ,
106- scale : open_file ( & path, "in_intensity_scale" )
107- . and_then ( | mut f| read ( & mut f ) )
124+ value : Mutex :: new ( open_file ( & path, "in_intensity_both_raw" ) . await ?) ,
125+ scale : try_open_and_read ( & path, "in_intensity_scale" )
126+ . await
108127 . unwrap_or ( 1_f64 ) ,
109- offset : open_file ( & path, "in_intensity_offset" )
110- . and_then ( | mut f| read ( & mut f ) )
128+ offset : try_open_and_read ( & path, "in_intensity_offset" )
129+ . await
111130 . unwrap_or ( 0_f64 ) ,
112131 } )
113132}
114133
115- fn parse_illuminance_input ( path : PathBuf ) -> Result < SensorType , Box < dyn Error > > {
134+ async fn parse_illuminance_input ( path : PathBuf ) -> Result < SensorType , ErrorBox > {
116135 Ok ( Illuminance {
117136 value : Mutex :: new (
118137 open_file ( & path, "in_illuminance_input" )
119- . or_else ( |_| open_file ( & path, "in_illuminance0_input" ) ) ?,
138+ . or_else ( |_| open_file ( & path, "in_illuminance0_input" ) )
139+ . await ?,
120140 ) ,
121141 scale : 1_f64 ,
122142 offset : 0_f64 ,
123143 } )
124144}
125145
126- fn parse_intensity_rgb ( path : PathBuf ) -> Result < SensorType , Box < dyn Error > > {
146+ async fn parse_intensity_rgb ( path : PathBuf ) -> Result < SensorType , ErrorBox > {
127147 Ok ( Intensity {
128- r : Mutex :: new ( open_file ( & path, "in_intensity_red_raw" ) ?) ,
129- g : Mutex :: new ( open_file ( & path, "in_intensity_green_raw" ) ?) ,
130- b : Mutex :: new ( open_file ( & path, "in_intensity_blue_raw" ) ?) ,
148+ r : Mutex :: new ( open_file ( & path, "in_intensity_red_raw" ) . await ?) ,
149+ g : Mutex :: new ( open_file ( & path, "in_intensity_green_raw" ) . await ?) ,
150+ b : Mutex :: new ( open_file ( & path, "in_intensity_blue_raw" ) . await ?) ,
131151 } )
132152}
133153
134- fn open_file ( path : & Path , name : & str ) -> Result < File , Box < dyn Error > > {
135- File :: open ( path. join ( name) ) . map_err ( Box :: < dyn Error > :: from)
154+ async fn open_file ( path : & Path , name : & str ) -> Result < File , ErrorBox > {
155+ File :: open ( path. join ( name) ) . await . map_err ( ErrorBox :: from)
136156}
0 commit comments