@@ -2,11 +2,11 @@ use std::collections::HashMap;
22
33use axum:: Router ;
44use axum:: extract:: { Path , State } ;
5- use axum:: response:: IntoResponse ;
65use axum:: routing:: { get, post, put} ;
76use bytes:: Bytes ;
87use chrono:: Utc ;
98use log:: { info, warn} ;
9+ use serde:: Serialize ;
1010use serde_json:: { Value , json} ;
1111use tokio:: sync:: MutexGuard ;
1212use uuid:: Uuid ;
@@ -17,7 +17,7 @@ use hue::api::{
1717 GroupedLightUpdate , Light , LightUpdate , RType , Resource , ResourceLink , Room , Scene ,
1818 SceneActive , SceneStatus , SceneUpdate , V1Reply ,
1919} ;
20- use hue:: error:: { HueError , HueResult } ;
20+ use hue:: error:: { HueApiV1Error , HueError , HueResult } ;
2121use hue:: legacy_api:: {
2222 ApiGroup , ApiGroupActionUpdate , ApiGroupUpdate2 , ApiLight , ApiLightStateUpdate ,
2323 ApiResourceType , ApiScene , ApiSceneAppData , ApiSceneType , ApiSceneVersion , ApiSensor ,
@@ -28,13 +28,14 @@ use crate::error::{ApiError, ApiResult};
2828use crate :: resource:: Resources ;
2929use crate :: routes:: auth:: STANDARD_CLIENT_KEY ;
3030use crate :: routes:: extractor:: Json ;
31+ use crate :: routes:: { ApiV1Error , ApiV1Result } ;
3132use crate :: server:: appstate:: AppState ;
3233
33- async fn get_api_config ( State ( state) : State < AppState > ) -> impl IntoResponse {
34+ async fn get_api_config ( State ( state) : State < AppState > ) -> Json < impl Serialize > {
3435 Json ( state. api_short_config ( ) . await )
3536}
3637
37- async fn post_api ( bytes : Bytes ) -> ApiResult < impl IntoResponse > {
38+ async fn post_api ( bytes : Bytes ) -> ApiV1Result < Json < impl Serialize > > {
3839 info ! ( "post: {bytes:?}" ) ;
3940 let json: NewUser = serde_json:: from_slice ( & bytes) ?;
4041
@@ -105,7 +106,7 @@ fn get_groups(res: &MutexGuard<Resources>, group_0: bool) -> ApiResult<HashMap<S
105106 Ok ( rooms)
106107}
107108
108- pub fn get_scene ( res : & Resources , owner : String , scene : & Scene ) -> ApiResult < ApiScene > {
109+ pub fn get_scene ( res : & Resources , owner : String , scene : & Scene ) -> ApiV1Result < ApiScene > {
109110 let lights = scene
110111 . actions
111112 . iter ( )
@@ -121,7 +122,7 @@ pub fn get_scene(res: &Resources, owner: String, scene: &Scene) -> ApiResult<Api
121122 ApiLightStateUpdate :: from ( sae. action . clone ( ) ) ,
122123 ) )
123124 } )
124- . collect :: < ApiResult < _ > > ( ) ?;
125+ . collect :: < ApiV1Result < _ > > ( ) ?;
125126
126127 let room_id = res. get_id_v1_index ( scene. group . rid ) ?;
127128
@@ -146,7 +147,7 @@ pub fn get_scene(res: &Resources, owner: String, scene: &Scene) -> ApiResult<Api
146147 } )
147148}
148149
149- fn get_scenes ( owner : & str , res : & MutexGuard < Resources > ) -> ApiResult < HashMap < String , ApiScene > > {
150+ fn get_scenes ( owner : & str , res : & MutexGuard < Resources > ) -> ApiV1Result < HashMap < String , ApiScene > > {
150151 let mut scenes = HashMap :: new ( ) ;
151152
152153 for rr in res. get_resources_by_type ( RType :: Scene ) {
@@ -165,7 +166,7 @@ fn get_scenes(owner: &str, res: &MutexGuard<Resources>) -> ApiResult<HashMap<Str
165166async fn get_api_user (
166167 state : State < AppState > ,
167168 Path ( username) : Path < String > ,
168- ) -> ApiResult < impl IntoResponse > {
169+ ) -> ApiV1Result < Json < impl Serialize > > {
169170 let lock = state. res . lock ( ) . await ;
170171
171172 Ok ( Json ( ApiUserConfig {
@@ -183,7 +184,7 @@ async fn get_api_user(
183184async fn get_api_user_resource (
184185 State ( state) : State < AppState > ,
185186 Path ( ( username, artype) ) : Path < ( String , ApiResourceType ) > ,
186- ) -> ApiResult < Json < Value > > {
187+ ) -> ApiV1Result < Json < Value > > {
187188 let lock = & state. res . lock ( ) . await ;
188189 match artype {
189190 ApiResourceType :: Config => Ok ( Json ( json ! ( state. api_config( username) . await ?) ) ) ,
@@ -201,26 +202,26 @@ async fn get_api_user_resource(
201202async fn post_api_user_resource (
202203 Path ( ( _username, resource) ) : Path < ( String , ApiResourceType ) > ,
203204 Json ( req) : Json < Value > ,
204- ) -> ApiResult < Json < Value > > {
205+ ) -> ApiV1Result < Json < Value > > {
205206 warn ! ( "POST v1 user resource unsupported" ) ;
206207 warn ! ( "Request: {req:?}" ) ;
207- Err ( ApiError :: V1CreateUnsupported ( resource) )
208+ Err ( ApiV1Error :: V1CreateUnsupported ( resource) )
208209}
209210
210211async fn put_api_user_resource (
211212 Path ( ( _username, _resource) ) : Path < ( String , String ) > ,
212213 Json ( req) : Json < Value > ,
213- ) -> impl IntoResponse {
214+ ) -> ApiV1Result < Json < impl Serialize > > {
214215 warn ! ( "PUT v1 user resource {req:?}" ) ;
215216 //Json(format!("user {username} resource {resource}"))
216- Json ( vec ! [ HueApiResult :: Success ( req) ] )
217+ Ok ( Json ( vec ! [ HueApiResult :: Success ( req) ] ) )
217218}
218219
219220#[ allow( clippy:: significant_drop_tightening) ]
220221async fn get_api_user_resource_id (
221222 State ( state) : State < AppState > ,
222223 Path ( ( username, resource, id) ) : Path < ( String , ApiResourceType , u32 ) > ,
223- ) -> ApiResult < impl IntoResponse > {
224+ ) -> ApiV1Result < Json < impl Serialize > > {
224225 log:: debug!( "GET v1 username={username} resource={resource:?} id={id}" ) ;
225226 let result = match resource {
226227 ApiResourceType :: Lights => {
@@ -260,7 +261,7 @@ async fn put_api_user_resource_id(
260261 State ( state) : State < AppState > ,
261262 Path ( ( username, artype, id) ) : Path < ( String , ApiResourceType , u32 ) > ,
262263 Json ( req) : Json < Value > ,
263- ) -> ApiResult < impl IntoResponse > {
264+ ) -> ApiV1Result < Json < Value > > {
264265 log:: debug!( "PUT v1 username={username} resource={artype:?} id={id}" ) ;
265266 log:: debug!( "JSON: {req:?}" ) ;
266267 match artype {
@@ -292,15 +293,15 @@ async fn put_api_user_resource_id(
292293 | ApiResourceType :: Scenes
293294 | ApiResourceType :: Schedules
294295 | ApiResourceType :: Sensors
295- | ApiResourceType :: Capabilities => Err ( ApiError :: V1CreateUnsupported ( artype) ) ,
296+ | ApiResourceType :: Capabilities => Err ( ApiV1Error :: V1CreateUnsupported ( artype) ) ,
296297 }
297298}
298299
299300async fn put_api_user_resource_id_path (
300301 State ( state) : State < AppState > ,
301302 Path ( ( _username, artype, id, path) ) : Path < ( String , ApiResourceType , u32 , String ) > ,
302303 Json ( req) : Json < Value > ,
303- ) -> ApiResult < Json < Value > > {
304+ ) -> ApiV1Result < Json < Value > > {
304305 match artype {
305306 ApiResourceType :: Lights => {
306307 log:: debug!( "req: {}" , serde_json:: to_string_pretty( & req) ?) ;
@@ -349,7 +350,7 @@ async fn put_api_user_resource_id_path(
349350 V1Reply :: for_group_path ( id, & path) . with_light_state_update ( & upd) ?
350351 }
351352 ApiGroupActionUpdate :: GroupUpdate ( upd) => {
352- let scene_id = upd. scene . parse ( ) ?;
353+ let scene_id = upd. scene . parse ( ) . map_err ( ApiError :: ParseIntError ) ?;
353354 let scene_uuid = lock. from_id_v1 ( scene_id) ?;
354355 let rlink = RType :: Scene . link_to ( scene_uuid) ;
355356 let updv2 = SceneUpdate :: new ( ) . with_recall_action ( Some ( SceneStatus {
@@ -404,7 +405,7 @@ async fn put_api_user_resource_id_path(
404405 | ApiResourceType :: Scenes
405406 | ApiResourceType :: Schedules
406407 | ApiResourceType :: Sensors
407- | ApiResourceType :: Capabilities => Err ( ApiError :: V1CreateUnsupported ( artype) ) ,
408+ | ApiResourceType :: Capabilities => Err ( ApiV1Error :: V1CreateUnsupported ( artype) ) ,
408409 }
409410}
410411
@@ -414,8 +415,8 @@ async fn put_api_user_resource_id_path(
414415/// even though this does not seem to ever have been a valid hue endpoint.
415416///
416417/// 2025-01-24: This response has been confirmed to work by Alexa and Peter Miller on discord.
417- pub async fn workaround_iconnect_hue ( ) -> impl IntoResponse {
418- Json ( json ! ( [ { "error" : { "type" : 1 , "address" : "/" , "description" : "unauthorized user" } } ] ) )
418+ pub async fn workaround_iconnect_hue ( ) -> ApiV1Result < ( ) > {
419+ Err ( HueApiV1Error :: UnauthorizedUser ) ?
419420}
420421
421422pub fn router ( ) -> Router < AppState > {
0 commit comments