diff --git a/hermes-ffi-test/src/json_round_trips.rs b/hermes-ffi-test/src/json_round_trips.rs index db8dcdda..60bb4ee5 100644 --- a/hermes-ffi-test/src/json_round_trips.rs +++ b/hermes-ffi-test/src/json_round_trips.rs @@ -86,6 +86,16 @@ round_trip_json!( hermes::InjectionResetCompleteMessage ); +round_trip_json!( + hermes_ffi_test_round_trip_injection_failed_json, + hermes::InjectionFailedMessage +); + +round_trip_json!( + hermes_ffi_test_round_trip_injection_reset_failed_json, + hermes::InjectionResetFailedMessage +); + round_trip_json!( hermes_ffi_test_round_trip_register_sound_json, hermes::RegisterSoundMessage diff --git a/hermes-ffi-test/src/lib.rs b/hermes-ffi-test/src/lib.rs index 2c946c24..caee218c 100644 --- a/hermes-ffi-test/src/lib.rs +++ b/hermes-ffi-test/src/lib.rs @@ -136,6 +136,22 @@ pub extern "C" fn hermes_ffi_test_round_trip_injection_reset_complete( wrap!(round_trip(input, output)) } +#[no_mangle] +pub extern "C" fn hermes_ffi_test_round_trip_injection_failed( + input: *const hermes_ffi::CInjectionFailedMessage, + output: *mut *const hermes_ffi::CInjectionFailedMessage, +) -> ffi_utils::SNIPS_RESULT { + wrap!(round_trip(input, output)) +} + +#[no_mangle] +pub extern "C" fn hermes_ffi_test_round_trip_injection_reset_failed( + input: *const hermes_ffi::CInjectionResetFailedMessage, + output: *mut *const hermes_ffi::CInjectionResetFailedMessage, +) -> ffi_utils::SNIPS_RESULT { + wrap!(round_trip(input, output)) +} + #[no_mangle] pub extern "C" fn hermes_ffi_test_round_trip_map_string_to_string_array( input: *const hermes_ffi::CMapStringToStringArray, diff --git a/hermes-ffi/src/ontology/injection.rs b/hermes-ffi/src/ontology/injection.rs index 21510ec9..c13b3418 100644 --- a/hermes-ffi/src/ontology/injection.rs +++ b/hermes-ffi/src/ontology/injection.rs @@ -302,6 +302,7 @@ impl AsRust for CInjectionStatusMessage { #[repr(C)] #[derive(Debug)] pub struct CInjectionCompleteMessage { + /// Nullable pub request_id: *const libc::c_char, } @@ -331,6 +332,7 @@ impl AsRust for CInjectionCompleteMessage { #[repr(C)] #[derive(Debug)] pub struct CInjectionResetRequestMessage { + /// Nullable pub request_id: *const libc::c_char, } @@ -360,6 +362,7 @@ impl AsRust for CInjectionResetRequestMess #[repr(C)] #[derive(Debug)] pub struct CInjectionResetCompleteMessage { + /// Nullable pub request_id: *const libc::c_char, } @@ -386,6 +389,74 @@ impl AsRust for CInjectionResetCompleteMe } } +#[repr(C)] +#[derive(Debug)] +pub struct CInjectionFailedMessage { + /// Nullable + pub request_id: *const libc::c_char, + pub context: *const libc::c_char, +} + +unsafe impl Sync for CInjectionFailedMessage {} + +impl Drop for CInjectionFailedMessage { + fn drop(&mut self) { + take_back_nullable_c_string!(self.request_id); + take_back_c_string!(self.context); + } +} + +impl CReprOf for CInjectionFailedMessage { + fn c_repr_of(message: hermes::InjectionFailedMessage) -> Fallible { + Ok(Self { + request_id: convert_to_nullable_c_string!(message.request_id), + context: convert_to_c_string!(message.context), + }) + } +} + +impl AsRust for CInjectionFailedMessage { + fn as_rust(&self) -> Fallible { + let request_id = create_optional_rust_string_from!(self.request_id); + let context = create_rust_string_from!(self.context); + Ok(hermes::InjectionFailedMessage { request_id, context }) + } +} + +#[repr(C)] +#[derive(Debug)] +pub struct CInjectionResetFailedMessage { + /// Nullable + pub request_id: *const libc::c_char, + pub context: *const libc::c_char, +} + +unsafe impl Sync for CInjectionResetFailedMessage {} + +impl Drop for CInjectionResetFailedMessage { + fn drop(&mut self) { + take_back_nullable_c_string!(self.request_id); + take_back_c_string!(self.context); + } +} + +impl CReprOf for CInjectionResetFailedMessage { + fn c_repr_of(message: hermes::InjectionResetFailedMessage) -> Fallible { + Ok(Self { + request_id: convert_to_nullable_c_string!(message.request_id), + context: convert_to_c_string!(message.context), + }) + } +} + +impl AsRust for CInjectionResetFailedMessage { + fn as_rust(&self) -> Fallible { + let request_id = create_optional_rust_string_from!(self.request_id); + let context = create_rust_string_from!(self.context); + Ok(hermes::InjectionResetFailedMessage { request_id, context }) + } +} + #[cfg(test)] mod tests { use super::super::tests::round_trip_test; @@ -536,4 +607,16 @@ mod tests { round_trip_test::<_, CInjectionResetCompleteMessage>(hermes::InjectionResetCompleteMessage::minimal_example()); round_trip_test::<_, CInjectionResetCompleteMessage>(hermes::InjectionResetCompleteMessage::full_example()); } + + #[test] + fn round_trip_injection_failed() { + round_trip_test::<_, CInjectionFailedMessage>(hermes::InjectionFailedMessage::minimal_example()); + round_trip_test::<_, CInjectionFailedMessage>(hermes::InjectionFailedMessage::full_example()); + } + + #[test] + fn round_trip_injection_reset_failed() { + round_trip_test::<_, CInjectionResetFailedMessage>(hermes::InjectionResetFailedMessage::minimal_example()); + round_trip_test::<_, CInjectionResetFailedMessage>(hermes::InjectionResetFailedMessage::full_example()); + } } diff --git a/hermes-ffi/src/protocol_handler/json.rs b/hermes-ffi/src/protocol_handler/json.rs index 951da0c1..ebf615a1 100644 --- a/hermes-ffi/src/protocol_handler/json.rs +++ b/hermes-ffi/src/protocol_handler/json.rs @@ -122,6 +122,8 @@ macro_rules! generate_json_c_symbols { $crate::generate_facade_subscribe_json!(hermes_injection_subscribe_injection_status_json = CInjectionFacade: subscribe_injection_status()); $crate::generate_facade_subscribe_json!(hermes_injection_subscribe_injection_complete_json = CInjectionFacade: subscribe_injection_complete()); $crate::generate_facade_subscribe_json!(hermes_injection_subscribe_injection_reset_complete_json = CInjectionFacade: subscribe_injection_reset_complete()); + $crate::generate_facade_subscribe_json!(hermes_injection_subscribe_injection_failed_json = CInjectionFacade: subscribe_injection_failed()); + $crate::generate_facade_subscribe_json!(hermes_injection_subscribe_injection_reset_failed_json = CInjectionFacade: subscribe_injection_reset_failed()); #[cfg(feature = "full_bindings")] pub mod full_bindings { diff --git a/hermes-ffi/src/protocol_handler/structures.rs b/hermes-ffi/src/protocol_handler/structures.rs index dc16cd72..31d14d56 100644 --- a/hermes-ffi/src/protocol_handler/structures.rs +++ b/hermes-ffi/src/protocol_handler/structures.rs @@ -109,6 +109,8 @@ macro_rules! generate_structures_c_symbols { $crate::generate_facade_subscribe!(hermes_injection_subscribe_injection_status = CInjectionFacade: subscribe_injection_status(|CInjectionStatusMessage|)); $crate::generate_facade_subscribe!(hermes_injection_subscribe_injection_complete = CInjectionFacade: subscribe_injection_complete(|CInjectionCompleteMessage|)); $crate::generate_facade_subscribe!(hermes_injection_subscribe_injection_reset_complete = CInjectionFacade: subscribe_injection_reset_complete(|CInjectionResetCompleteMessage|)); + $crate::generate_facade_subscribe!(hermes_injection_subscribe_injection_failed = CInjectionFacade: subscribe_injection_failed(|CInjectionFailedMessage|)); + $crate::generate_facade_subscribe!(hermes_injection_subscribe_injection_reset_failed = CInjectionFacade: subscribe_injection_reset_failed(|CInjectionResetFailedMessage|)); $crate::generate_facade_publish!(hermes_tts_publish_register_sound = CTtsFacade: publish_register_sound(CRegisterSoundMessage)); @@ -122,6 +124,8 @@ macro_rules! generate_structures_c_symbols { $crate::generate_destroy!(hermes_drop_injection_status_message for CInjectionStatusMessage); $crate::generate_destroy!(hermes_drop_injection_complete_message for CInjectionCompleteMessage); $crate::generate_destroy!(hermes_drop_injection_reset_complete_message for CInjectionResetCompleteMessage); + $crate::generate_destroy!(hermes_drop_injection_failed_message for CInjectionFailedMessage); + $crate::generate_destroy!(hermes_drop_injection_reset_failed_message for CInjectionResetFailedMessage); #[cfg(feature = "full_bindings")] pub mod full_bindings { diff --git a/hermes-inprocess/src/lib.rs b/hermes-inprocess/src/lib.rs index 08941144..50099a75 100644 --- a/hermes-inprocess/src/lib.rs +++ b/hermes-inprocess/src/lib.rs @@ -1067,6 +1067,16 @@ struct InjectionResetComplete { message: InjectionResetCompleteMessage, } +#[derive(Debug)] +struct InjectionFailed { + message: InjectionFailedMessage, +} + +#[derive(Debug)] +struct InjectionResetFailed { + message: InjectionResetFailedMessage, +} + impl InjectionFacade for InProcessComponent { fn publish_injection_request(&self, request: InjectionRequestMessage) -> Fallible<()> { self.publish(InjectionPerform { request }) @@ -1091,6 +1101,14 @@ impl InjectionFacade for InProcessComponent { fn subscribe_injection_reset_complete(&self, handler: Callback) -> Fallible<()> { subscribe!(self, InjectionResetComplete { message }, handler) } + + fn subscribe_injection_failed(&self, handler: Callback) -> Fallible<()> { + subscribe!(self, InjectionFailed { message }, handler) + } + + fn subscribe_injection_reset_failed(&self, handler: Callback) -> Fallible<()> { + subscribe!(self, InjectionResetFailed { message }, handler) + } } impl InjectionBackendFacade for InProcessComponent { @@ -1117,6 +1135,14 @@ impl InjectionBackendFacade for InProcessComponent { fn publish_injection_reset_complete(&self, message: InjectionResetCompleteMessage) -> Fallible<()> { self.publish(InjectionResetComplete { message }) } + + fn publish_injection_failed(&self, message: InjectionFailedMessage) -> Fallible<()> { + self.publish(InjectionFailed { message }) + } + + fn publish_injection_reset_failed(&self, message: InjectionResetFailedMessage) -> Fallible<()> { + self.publish(InjectionResetFailed { message }) + } } #[cfg(test)] diff --git a/hermes-mqtt/src/lib.rs b/hermes-mqtt/src/lib.rs index 2c81a2bc..d862b0ff 100644 --- a/hermes-mqtt/src/lib.rs +++ b/hermes-mqtt/src/lib.rs @@ -720,6 +720,8 @@ impl InjectionFacade for MqttComponentFacade { s!(subscribe_injection_status &HermesTopic::Injection(InjectionCommand::Status);); s!(subscribe_injection_complete &HermesTopic::Injection(InjectionCommand::Complete);); s!(subscribe_injection_reset_complete &HermesTopic::Injection(InjectionCommand::ResetComplete);); + s!(subscribe_injection_failed &HermesTopic::Injection(InjectionCommand::Failed);); + s!(subscribe_injection_reset_failed &HermesTopic::Injection(InjectionCommand::ResetFailed);); } impl InjectionBackendFacade for MqttComponentFacade { @@ -729,6 +731,8 @@ impl InjectionBackendFacade for MqttComponentFacade { p!(publish_injection_status &HermesTopic::Injection(InjectionCommand::Status);); p!(publish_injection_complete &HermesTopic::Injection(InjectionCommand::Complete);); p!(publish_injection_reset_complete &HermesTopic::Injection(InjectionCommand::ResetComplete);); + p!(publish_injection_failed &HermesTopic::Injection(InjectionCommand::Failed);); + p!(publish_injection_reset_failed &HermesTopic::Injection(InjectionCommand::ResetFailed);); } impl MqttHermesProtocolHandler { diff --git a/hermes-mqtt/src/topics.rs b/hermes-mqtt/src/topics.rs index 0b945483..e16d611a 100644 --- a/hermes-mqtt/src/topics.rs +++ b/hermes-mqtt/src/topics.rs @@ -280,6 +280,7 @@ impl HermesTopic { ComponentCommand::VersionRequest, )), Some("complete") => Some(Injection(Complete)), + Some("failed") => Some(Injection(Failed)), Some("version") => Some(HermesTopic::Component( None, Component::Injection, @@ -298,6 +299,7 @@ impl HermesTopic { Some("reset") => match comps.next() { Some("perform") => Some(Injection(ResetRequest)), Some("complete") => Some(Injection(ResetComplete)), + Some("failed") => Some(Injection(ResetFailed)), _ => None, }, _ => None, @@ -533,6 +535,8 @@ pub enum InjectionCommand { Complete, ResetRequest, ResetComplete, + Failed, + ResetFailed, } impl ToPath for InjectionCommand { @@ -540,6 +544,7 @@ impl ToPath for InjectionCommand { match &self { InjectionCommand::ResetRequest => "reset/perform".into(), InjectionCommand::ResetComplete => "reset/complete".into(), + InjectionCommand::ResetFailed => "reset/failed".into(), _ => self.as_path_default(), } } @@ -831,6 +836,14 @@ mod tests { HermesTopic::Injection(InjectionCommand::ResetComplete), "hermes/injection/reset/complete", ), + ( + HermesTopic::Injection(InjectionCommand::Failed), + "hermes/injection/failed", + ), + ( + HermesTopic::Injection(InjectionCommand::ResetFailed), + "hermes/injection/reset/failed", + ), ( HermesTopic::Component(None, Component::Injection, ComponentCommand::VersionRequest), "hermes/injection/versionRequest", diff --git a/hermes-test-suite/src/lib.rs b/hermes-test-suite/src/lib.rs index e7f7cbec..ef12aabd 100644 --- a/hermes-test-suite/src/lib.rs +++ b/hermes-test-suite/src/lib.rs @@ -257,5 +257,9 @@ macro_rules! test_suite { injection_backend.subscribe_injection_reset_request <= InjectionResetRequestMessage | injection.publish_injection_reset_request); t!(injection_reset_complete: injection.subscribe_injection_reset_complete <= InjectionResetCompleteMessage | injection_backend.publish_injection_reset_complete); + t!(injection_failed: + injection.subscribe_injection_failed <= InjectionFailedMessage | injection_backend.publish_injection_failed); + t!(injection_reset_failed: + injection.subscribe_injection_reset_failed <= InjectionResetFailedMessage | injection_backend.publish_injection_reset_failed); }; } diff --git a/hermes/src/lib.rs b/hermes/src/lib.rs index 4cf3c966..0b1f8fe8 100644 --- a/hermes/src/lib.rs +++ b/hermes/src/lib.rs @@ -271,6 +271,8 @@ pub trait InjectionFacade: ComponentFacade { fn subscribe_injection_status(&self, handler: Callback) -> Fallible<()>; fn subscribe_injection_complete(&self, handler: Callback) -> Fallible<()>; fn subscribe_injection_reset_complete(&self, handler: Callback) -> Fallible<()>; + fn subscribe_injection_failed(&self, handler: Callback) -> Fallible<()>; + fn subscribe_injection_reset_failed(&self, handler: Callback) -> Fallible<()>; } /// The facade the injecter must use to receive its orders and advertise when it has finished @@ -281,6 +283,8 @@ pub trait InjectionBackendFacade: ComponentBackendFacade { fn publish_injection_status(&self, status: InjectionStatusMessage) -> Fallible<()>; fn publish_injection_complete(&self, message: InjectionCompleteMessage) -> Fallible<()>; fn publish_injection_reset_complete(&self, message: InjectionResetCompleteMessage) -> Fallible<()>; + fn publish_injection_failed(&self, message: InjectionFailedMessage) -> Fallible<()>; + fn publish_injection_reset_failed(&self, message: InjectionResetFailedMessage) -> Fallible<()>; } pub trait HermesProtocolHandler: Send + Sync + std::fmt::Display { diff --git a/hermes/src/ontology/injection.rs b/hermes/src/ontology/injection.rs index 65b7a6a1..49eaa655 100644 --- a/hermes/src/ontology/injection.rs +++ b/hermes/src/ontology/injection.rs @@ -97,6 +97,17 @@ pub struct InjectionCompleteMessage { impl<'de> HermesMessage<'de> for InjectionCompleteMessage {} +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Example)] +#[serde(rename_all = "camelCase")] +pub struct InjectionFailedMessage { + /// The id of the `InjectionFailedMessage` + pub request_id: Option, + /// The context of the failure + pub context: String, +} + +impl<'de> HermesMessage<'de> for InjectionFailedMessage {} + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Example)] #[serde(rename_all = "camelCase")] pub struct InjectionResetRequestMessage { @@ -115,6 +126,17 @@ pub struct InjectionResetCompleteMessage { impl<'de> HermesMessage<'de> for InjectionResetCompleteMessage {} +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Example)] +#[serde(rename_all = "camelCase")] +pub struct InjectionResetFailedMessage { + /// The id of the `InjectionResetFailedMessage` + pub request_id: Option, + /// The context of the failure + pub context: String, +} + +impl<'de> HermesMessage<'de> for InjectionResetFailedMessage {} + #[cfg(test)] mod test { use serde_json; diff --git a/platforms/c/libsnips_hermes.h b/platforms/c/libsnips_hermes.h index c1dd7823..e0009631 100644 --- a/platforms/c/libsnips_hermes.h +++ b/platforms/c/libsnips_hermes.h @@ -623,6 +623,9 @@ typedef struct { } CErrorMessage; typedef struct { + /** + * Nullable + */ const char *request_id; } CInjectionCompleteMessage; @@ -632,9 +635,28 @@ typedef struct { } CInjectionFacade; typedef struct { + /** + * Nullable + */ + const char *request_id; + const char *context; +} CInjectionFailedMessage; + +typedef struct { + /** + * Nullable + */ const char *request_id; } CInjectionResetCompleteMessage; +typedef struct { + /** + * Nullable + */ + const char *request_id; + const char *context; +} CInjectionResetFailedMessage; + typedef struct { const char *last_injection_date; } CInjectionStatusMessage; @@ -689,6 +711,9 @@ typedef struct { } CInjectionRequestMessage; typedef struct { + /** + * Nullable + */ const char *request_id; } CInjectionResetRequestMessage; @@ -933,8 +958,12 @@ SNIPS_RESULT hermes_drop_injection_complete_message(const CInjectionCompleteMess SNIPS_RESULT hermes_drop_injection_facade(const CInjectionFacade *cstruct); +SNIPS_RESULT hermes_drop_injection_failed_message(const CInjectionFailedMessage *cstruct); + SNIPS_RESULT hermes_drop_injection_reset_complete_message(const CInjectionResetCompleteMessage *cstruct); +SNIPS_RESULT hermes_drop_injection_reset_failed_message(const CInjectionResetFailedMessage *cstruct); + SNIPS_RESULT hermes_drop_injection_status_message(const CInjectionStatusMessage *cstruct); SNIPS_RESULT hermes_drop_intent_message(const CIntentMessage *cstruct); @@ -972,9 +1001,15 @@ SNIPS_RESULT hermes_injection_publish_injection_status_request(const CInjectionF SNIPS_RESULT hermes_injection_subscribe_injection_complete(const CInjectionFacade *facade, void (*handler)(const CInjectionCompleteMessage*, void*)); +SNIPS_RESULT hermes_injection_subscribe_injection_failed(const CInjectionFacade *facade, + void (*handler)(const CInjectionFailedMessage*, void*)); + SNIPS_RESULT hermes_injection_subscribe_injection_reset_complete(const CInjectionFacade *facade, void (*handler)(const CInjectionResetCompleteMessage*, void*)); +SNIPS_RESULT hermes_injection_subscribe_injection_reset_failed(const CInjectionFacade *facade, + void (*handler)(const CInjectionResetFailedMessage*, void*)); + SNIPS_RESULT hermes_injection_subscribe_injection_status(const CInjectionFacade *facade, void (*handler)(const CInjectionStatusMessage*, void*)); diff --git a/platforms/c/libsnips_hermes_full.h b/platforms/c/libsnips_hermes_full.h index b6212f38..95ea0777 100644 --- a/platforms/c/libsnips_hermes_full.h +++ b/platforms/c/libsnips_hermes_full.h @@ -713,6 +713,9 @@ typedef struct { } CHotwordFacade; typedef struct { + /** + * Nullable + */ const char *request_id; } CInjectionCompleteMessage; @@ -721,6 +724,14 @@ typedef struct { void *user_data; } CInjectionFacade; +typedef struct { + /** + * Nullable + */ + const char *request_id; + const char *context; +} CInjectionFailedMessage; + typedef struct { const char *key; const CStringArray *value; @@ -755,10 +766,24 @@ typedef struct { } CInjectionRequestMessage; typedef struct { + /** + * Nullable + */ const char *request_id; } CInjectionResetCompleteMessage; typedef struct { + /** + * Nullable + */ + const char *request_id; + const char *context; +} CInjectionResetFailedMessage; + +typedef struct { + /** + * Nullable + */ const char *request_id; } CInjectionResetRequestMessage; @@ -1255,10 +1280,14 @@ SNIPS_RESULT hermes_drop_injection_complete_message(const CInjectionCompleteMess SNIPS_RESULT hermes_drop_injection_facade(const CInjectionFacade *cstruct); +SNIPS_RESULT hermes_drop_injection_failed_message(const CInjectionFailedMessage *cstruct); + SNIPS_RESULT hermes_drop_injection_request_message(const CInjectionRequestMessage *cstruct); SNIPS_RESULT hermes_drop_injection_reset_complete_message(const CInjectionResetCompleteMessage *cstruct); +SNIPS_RESULT hermes_drop_injection_reset_failed_message(const CInjectionResetFailedMessage *cstruct); + SNIPS_RESULT hermes_drop_injection_reset_request_message(const CInjectionResetRequestMessage *cstruct); SNIPS_RESULT hermes_drop_injection_status_message(const CInjectionStatusMessage *cstruct); @@ -1343,9 +1372,15 @@ SNIPS_RESULT hermes_injection_publish_injection_status_request(const CInjectionF SNIPS_RESULT hermes_injection_subscribe_injection_complete(const CInjectionFacade *facade, void (*handler)(const CInjectionCompleteMessage*, void*)); +SNIPS_RESULT hermes_injection_subscribe_injection_failed(const CInjectionFacade *facade, + void (*handler)(const CInjectionFailedMessage*, void*)); + SNIPS_RESULT hermes_injection_subscribe_injection_reset_complete(const CInjectionFacade *facade, void (*handler)(const CInjectionResetCompleteMessage*, void*)); +SNIPS_RESULT hermes_injection_subscribe_injection_reset_failed(const CInjectionFacade *facade, + void (*handler)(const CInjectionResetFailedMessage*, void*)); + SNIPS_RESULT hermes_injection_subscribe_injection_status(const CInjectionFacade *facade, void (*handler)(const CInjectionStatusMessage*, void*));