From 4df5aef266cc0fd642240a4e2e5a4e942c86c623 Mon Sep 17 00:00:00 2001 From: James McNally Date: Thu, 12 Sep 2024 07:30:54 +0100 Subject: [PATCH 1/2] feat: Function to Wrap Function in Error Added the ability to write a function that follows LabVIEWS error semantics with the error cluster. Refs: #35 --- changelog.md | 2 +- labview-interop/src/errors.rs | 36 ++++++--- labview-interop/src/types/boolean.rs | 19 +++++ labview-interop/src/types/lv_errors.rs | 72 ++++++++++++++++-- labview-test-library/src/error_clusters.rs | 22 +++++- .../Error Tests/Error Tests.lvclass | 27 +++++++ ...Error Wrapping - Execute if No Error In.vi | Bin 0 -> 14380 bytes ...Error Wrapping - No Execute On Error In.vi | Bin 0 -> 14392 bytes ...r Wrapping - Sets Error For Inner Error.vi | Bin 0 -> 12380 bytes labview-test-project/rust-interop-test.lvlps | 2 +- 10 files changed, 161 insertions(+), 19 deletions(-) create mode 100644 labview-test-project/Error Tests/test Error Wrapping - Execute if No Error In.vi create mode 100644 labview-test-project/Error Tests/test Error Wrapping - No Execute On Error In.vi create mode 100644 labview-test-project/Error Tests/test Error Wrapping - Sets Error For Inner Error.vi diff --git a/changelog.md b/changelog.md index f2732e4..9d37d09 100644 --- a/changelog.md +++ b/changelog.md @@ -8,8 +8,8 @@ * Added support for `LVStatusCode` and retrieving error descriptions from LabVIEW. * Added api for accessing dimensions of arrays. +* Add API to error clusters to execute the rust code following the LabVIEW error semantics. * Lazily load LabVIEW functions to allow time for LabVIEW to load. - #### Fixes * Expose NumericArrayResize trait to users of the Library. diff --git a/labview-interop/src/errors.rs b/labview-interop/src/errors.rs index 1d1d78a..96406d8 100644 --- a/labview-interop/src/errors.rs +++ b/labview-interop/src/errors.rs @@ -55,11 +55,9 @@ //! This enum has custom errors for our internal use, we can hold MgErrors, and as last resort we can also hold //! LVError -use thiserror::Error; - use crate::types::LVStatusCode; - use num_enum::{IntoPrimitive, TryFromPrimitive}; +use thiserror::Error; /// the conversion from LVInteropError back to LVStatusCode is important /// to return the status in extern "C" functions back to LV @@ -67,20 +65,32 @@ impl From> for LVStatusCode { fn from(value: Result) -> Self { match value { Ok(_) => LVStatusCode::SUCCESS, - Err(err) => err.into(), + Err(err) => (&err).into(), } } } -impl From for LVStatusCode { - fn from(value: LVInteropError) -> Self { +impl From<&LVInteropError> for LVStatusCode { + fn from(value: &LVInteropError) -> Self { match value { LVInteropError::LabviewMgError(e) => e.into(), - LVInteropError::InternalError(e) => e.into(), // TODO - LVInteropError::LabviewError(e) => e, + LVInteropError::InternalError(e) => e.into(), + LVInteropError::LabviewError(e) => *e, } } } +impl From for LVStatusCode { + fn from(value: LVInteropError) -> Self { + (&value).into() + } +} + +impl From for LVInteropError { + fn from(status: LVStatusCode) -> Self { + LVInteropError::LabviewError(status) + } +} + /// MgError is the subset of LabVIEW errors that may occur when dealing with the memory manager /// So in the context of Rust-LabVIEW-interop these are the kind of labview errors we may trigger within the library /// @@ -344,10 +354,16 @@ impl TryFrom for MgError { } } +impl From<&MgError> for LVStatusCode { + fn from(errcode: &MgError) -> LVStatusCode { + let erri32: i32 = *errcode as i32; + erri32.into() + } +} + impl From for LVStatusCode { fn from(errcode: MgError) -> LVStatusCode { - let erri32: i32 = errcode.into(); - erri32.into() + (&errcode).into() } } diff --git a/labview-interop/src/types/boolean.rs b/labview-interop/src/types/boolean.rs index c12debb..f56e3e4 100644 --- a/labview-interop/src/types/boolean.rs +++ b/labview-interop/src/types/boolean.rs @@ -8,6 +8,10 @@ /// /// You can use `.into()` to convert between this and /// rust [`bool`] types. +/// +/// NOTE: This does not seem to work if the boolean is +/// used as a parameter in a call library function node. +/// In that case you should convert to numeric first. #[repr(transparent)] #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub struct LVBool(u8); @@ -65,4 +69,19 @@ mod tests { let value: bool = LVBool(23).into(); assert_eq!(value, true) } + + #[test] + fn lv_bool_in_if_statement() { + if LV_TRUE.into() { + assert!(true); + } else { + assert!(false); + } + + if LV_FALSE.into() { + assert!(false); + } else { + assert!(true); + } + } } diff --git a/labview-interop/src/types/lv_errors.rs b/labview-interop/src/types/lv_errors.rs index a3c04e1..bcee528 100644 --- a/labview-interop/src/types/lv_errors.rs +++ b/labview-interop/src/types/lv_errors.rs @@ -2,8 +2,6 @@ //! //! This is only available in 64 bit currently due to restrictions //! on unaligned pointer access. -use std::borrow::Cow; - #[cfg(feature = "link")] use crate::errors::Result; use crate::errors::{LVInteropError, MgError}; @@ -12,6 +10,7 @@ use crate::memory::UPtr; use crate::types::LStrHandle; use crate::types::LVBool; use crate::types::LVStatusCode; +use std::borrow::Cow; labview_layout!( /// The cluster format used by LabVIEW for transmitting errors. @@ -22,12 +21,19 @@ labview_layout!( } ); +impl<'a> ErrorCluster<'a> { + /// Does the error cluster contain an error. + pub fn is_err(&self) -> bool { + self.status.into() + } +} + /// The pointer as passed by LabVIEW when using "Handles By Value" for type. /// /// Debugging shows only one level of indirection hence UPtr here. /// /// It is recommended to manually call `ErrorClusterPtr::as_ref` or `ErrorClusterPtr::as_mut` -/// so that null pointeres can be detected. +/// so that null pointers can be detected. /// /// Many string manipulation functions are only available with the `link` feature enabled so /// it can manipulate LabVIEW Strings. @@ -44,6 +50,52 @@ fn format_error_source(source: &str, description: &str) -> String { } } +#[cfg(feature = "link")] +impl ErrorClusterPtr<'_> { + /// Wrap the provided function in error handling to match LabVIEW semantics. + /// + /// i.e. no execution on error in, convert return errors into error cluster. + /// + /// ## Parameters + /// + /// - `return_on_error` - The value to return if an error. + /// - `function` - The function to wrap. This is intended to be a closure for + /// easy use. + /// + /// ## Example + /// + /// ```rust + /// use labview_interop::types::ErrorClusterPtr; + /// use labview_interop::errors::LVInteropError; + /// use labview_interop::types::LStrHandle; + /// + /// #[no_mangle] + /// pub extern "C" fn example_function(mut error_cluster: ErrorClusterPtr, mut string_input: LStrHandle) -> i32 { + /// error_cluster.wrap_function(42, || -> Result { + /// // Do some work + /// string_input.set_str("Hello World")?; + /// Ok(42) + /// }) + /// } + /// ``` + pub fn wrap_function std::result::Result>( + &mut self, + return_on_error: R, + function: F, + ) -> R { + if self.is_err() { + return return_on_error; + } + match function() { + Ok(value) => value, + Err(error) => { + let _ = error.write_error(self); + return_on_error + } + } + } +} + #[cfg(feature = "link")] mod error_cluster_link_features { use super::*; @@ -89,7 +141,7 @@ mod error_cluster_link_features { pub trait ToLvError { /// The code for the error. Default is 42. fn code(&self) -> LVStatusCode { - MgError::BogusError.into() // code 42, Generic Error + (&MgError::BogusError).into() // code 42, Generic Error } /// True if is error. Default is true. @@ -112,7 +164,7 @@ pub trait ToLvError { /// /// This requires the `link` feature to enable string manipulation. #[cfg(feature = "link")] - fn write_error(&self, error_cluster: ErrorClusterPtr) -> Result<()> { + fn write_error(&self, error_cluster: &mut ErrorClusterPtr) -> Result<()> { let cluster = unsafe { error_cluster.as_ref_mut()? }; let code = self.code(); let source = self.source(); @@ -128,6 +180,16 @@ pub trait ToLvError { } impl ToLvError for LVInteropError { + fn code(&self) -> LVStatusCode { + self.into() + } + fn source(&self) -> Cow<'_, str> { + std::error::Error::source(self) + .map(|s| s.to_string()) + .unwrap_or_default() + .into() + } + fn description(&self) -> Cow<'_, str> { self.to_string().into() } diff --git a/labview-test-library/src/error_clusters.rs b/labview-test-library/src/error_clusters.rs index 607f603..5ac704c 100644 --- a/labview-test-library/src/error_clusters.rs +++ b/labview-test-library/src/error_clusters.rs @@ -1,3 +1,4 @@ +use labview_interop::errors::LVInteropError; /// A simple type for testing the error integration. /// use labview_interop::types::{ErrorClusterPtr, ToLvError}; @@ -17,9 +18,26 @@ impl ToLvError for ErrorText { #[cfg(target_pointer_width = "64")] #[no_mangle] -pub extern "C" fn set_error_cluster(error_cluster: ErrorClusterPtr) -> LVStatusCode { +pub extern "C" fn set_error_cluster(mut error_cluster: ErrorClusterPtr) -> LVStatusCode { let error = ErrorText("This is a test"); - error.write_error(error_cluster).into() + error.write_error(&mut error_cluster).into() +} + +/// Check scenarios for the error cluster function wrapping. +#[cfg(target_pointer_width = "64")] +#[no_mangle] +pub extern "C" fn wrap_function( + mut error_cluster: ErrorClusterPtr, + mut text: LStrHandle, + inner_error: i16, +) -> i32 { + error_cluster.wrap_function(42, || -> Result { + text.set_str("Hello World")?; + if inner_error != 0 { + return Err(LVInteropError::from(LVStatusCode::from(1))); + } + Ok(0) + }) } #[no_mangle] diff --git a/labview-test-project/Error Tests/Error Tests.lvclass b/labview-test-project/Error Tests/Error Tests.lvclass index f986deb..f2c5404 100644 --- a/labview-test-project/Error Tests/Error Tests.lvclass +++ b/labview-test-project/Error Tests/Error Tests.lvclass @@ -78,4 +78,31 @@ 1 1342710288 + + )!#!!!!!!!)!"1!&!!!-!%!!!@````]!!!!"!!%!!!%A!!!!#1!-1#%'=X2B>(6T!!!,1!-!"'.P:'5!!""!-0````]'=W^V=G.F!!!71&!!!Q!!!!%!!AFF=H*P=C"P>81!"!!!!#R!=!!?!!!6%U6S=G^S)&2F=X2T,GRW9WRB=X-!$&2F=X2$98.F)'^V>!!!)%"1!!-!!!!"!!)4:8*S<X)A;7YA+'ZP)'6S=G^S+1!K1(!!(A!!&2.&=H*P=C"5:8.U=SZM>G.M98.T!!N5:8.U1W&T:3"J<A"B!0!!$!!$!!1!"!!&!!1!"!!%!!1!"A!%!!1!"Q-!!(A!!!U)!!!!!!!!!!!!!!U,!!!!!!!!!!!!!!!!!!!!!!!!#A!!!!!!!!!!!!!!%A!!$1!!!!Q!!!!!!!!!!!!!!1!)!!!!!! + -1 + 16777216 + true + 1 + 1 + 1342710288 + + + )!#!!!!!!!)!"1!&!!!-!%!!!@````]!!!!"!!%!!!%A!!!!#1!-1#%'=X2B>(6T!!!,1!-!"'.P:'5!!""!-0````]'=W^V=G.F!!!71&!!!Q!!!!%!!AFF=H*P=C"P>81!"!!!!#R!=!!?!!!6%U6S=G^S)&2F=X2T,GRW9WRB=X-!$&2F=X2$98.F)'^V>!!!)%"1!!-!!!!"!!)4:8*S<X)A;7YA+'ZP)'6S=G^S+1!K1(!!(A!!&2.&=H*P=C"5:8.U=SZM>G.M98.T!!N5:8.U1W&T:3"J<A"B!0!!$!!$!!1!"!!&!!1!"!!%!!1!"A!%!!1!"Q-!!(A!!!U)!!!!!!!!!!!!!!U,!!!!!!!!!!!!!!!!!!!!!!!!#A!!!!!!!!!!!!!!%A!!$1!!!!Q!!!!!!!!!!!!!!1!)!!!!!! + -1 + 32 + true + 1 + 1 + 1074278928 + + + )!#!!!!!!!)!"1!&!!!-!%!!!@````]!!!!"!!%!!!%A!!!!#1!-1#%'=X2B>(6T!!!,1!-!"'.P:'5!!""!-0````]'=W^V=G.F!!!71&!!!Q!!!!%!!AFF=H*P=C"P>81!"!!!!#R!=!!?!!!6%U6S=G^S)&2F=X2T,GRW9WRB=X-!$&2F=X2$98.F)'^V>!!!)%"1!!-!!!!"!!)4:8*S<X)A;7YA+'ZP)'6S=G^S+1!K1(!!(A!!&2.&=H*P=C"5:8.U=SZM>G.M98.T!!N5:8.U1W&T:3"J<A"B!0!!$!!$!!1!"!!&!!1!"!!%!!1!"A!%!!1!"Q-!!(A!!!U)!!!!!!!!!!!!!!U,!!!!!!!!!!!!!!!!!!!!!!!!#A!!!!!!!!!!!!!!%A!!$1!!!!Q!!!!!!!!!!!!!!1!)!!!!!! + -1 + 16777216 + true + 1 + 1 + 1342710288 + diff --git a/labview-test-project/Error Tests/test Error Wrapping - Execute if No Error In.vi b/labview-test-project/Error Tests/test Error Wrapping - Execute if No Error In.vi new file mode 100644 index 0000000000000000000000000000000000000000..94625043b36ad0094b93e1551cb889e1553c41f2 GIT binary patch literal 14380 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

flvi^vkb#^UZ%COfMs0?BMrGD>hKuu( z-Ye|Z*r%lX?4HWP=l9h;F$k|xmZ=VWW?QGt{q#hJeO`6v7JZ9QdjR{xNJ)K7D4f%M z=8459`uR*e3n(@1zK0;1pl_&YCnTB{!eVkI>FIG%GSO0s4kir>bly#c+hYqdt4wTk zM4QVLCHh6ple5I%H9!&FssR z&JL_X+Tq7nBxhH)h(f(p2HAP!^Dpgk%$q*rAH`6~2r<=5jxdJ7=7SxGBOjDJdwN*zJPN0ZlPUGDi7b zp$?fKe5(GPms(7`rRizSEzr4AWLx0>f)ViffUz`Se5=Zl-aIg-}ye$P8ZCAJD9cEeI$}DZag|td{kt0O3fMH=eDyayf}E*;i{Z z0zjj54UF;WyN}*!exH6vCXSLG+%OcV5tU95neLX9Zow)hng0WeQk$Js!;S7!_dFDco&x@%_%j`qUr~-qA2Y-$7=rAa7jFrweg~It}fg)g_f?MeBh_SmATc-}SpW>?)5btMBzJG(dIcVenS=BTX+#g9^NGjY9go4cXMocH=Gyud5HNO^=8XN9X2**ChHk1XMQ{ zZQkRgU`CJsu#NS?KG&Y9g(vM+M#A_);+HQr5e<+~v-g62D4KL;gYS7`CHkf`3dD=MDTDcZmBiDve}9ajHrEKy0?HH@P#55BG9 z7*IA?SYDA<9(q@_dR4lO$CEsa5|t!xlvU|M9uM>g1Txs07l-<-yt!V-GUVVawn|zPT$YbnEd&+t#-ueyP-|K1VbjM;snU_*ApS zscA7xK9pn0Sy78eZGKk%J>454Wz(aim5Gl&xdlHf%uyMKXRf2PQERH&Zjj`T4Lm^9 z=j+KcC@@wI3TgVt3Gccw@uSWT0~bze6vvQK^PR$g_>A zK5T)7mI8qo+hA}Z-$+F)FbVRnS@6YbWjp0@rK@)kRo`!x$CwJ0w@elhNyIC>e_RUT zPl|<6P%=Ds&4Y9EB#3M)KRw{2>}m-MP$(S<@NhQ2+|!J9c|%I=-h5+#Bg^V_n&h;Q zBRj+}-}DFv+~A39ca51mqr0Dh>DSj}Z^g;_P&>112CCveTV$)fyr-AFt$er9t%IsbVTqANvHt&-guuV8t0#16|b zI07*%MuyLcvcqK+T{U$z-aDg;DVlvJc=KlcUHX)(FZ20_6Vm9cJFFyXY-GGFQo9UZ zxzDB}Kk&|n<>js=(JGo3EgF6|XDuI(%nQGy(L6bA$vXGWlgLZDwsAFP?yai@{nN~E zaDT0-15(8ggKjU_1JWPWoAeMU6>5y!O~E!E{*+}8Q(i6ig6h4fncsQO&VAQQe=GKhj5R{ts0LG?=ng+A;(@T;s=_6H~j3`r9EEI`l&j)AJNF}Y@9<}4LH6_X)u)0ex$VIA2 zyRR94V1tqLw&2*6KBpcfVZ);I{Fm)bwVG?+3MNt`57K9shK&cqcki~gn5WT0BAjc4 zWM$aN(EZ&!Syvs?Tw+~o?z`=Wh2$%LoD}Vka`h}^jVo*0{`{5j@Fu*8eUHPFnA4Lb zv3!P>7rknRAg?mC4emjcfq;#n(RUG8l2F%QrJBt0G3WJ|Y`i_<(sG2?M~a;xFQg0A zLoIloUMqbGQN12&8%#9#%qGcwh>pzp{-=KYCNs@2vlru(+ii>N_0NmyWcgSz<6^gF zr6L+WzrL6(ZtJOT1LrQg5HNl4V@+_<$`qAfF)-*47 z$)( zceGY0k7q$u##aKE4KT63v*o9I&iN(W^`Np8FJhb8`JpD}#64+!^ty=6J^TJ^#cC`z zT3jmM$lATR_%1(PzqeUln4pv?>m0?FvHa)TyVHoFK5rcXm4@){ zWpkI*o3`z36uT+4M`nlb17m1NT;7a#DZWmjA!5H_C^No2fBa-%&=lvThJ1IAvq^#| zmT_i*sViZ+{-lp;Oyr|aV;mtd&zx?2ffLlfWqPuGW6S@+Ii_6BrVf_AR6I;(>{5Ff z$9EwP3+JkdJuiobWn5!3^*mq77x^fLOt0%P+Elhf0Q4Zq ziE@~?LWt8B+uqT-REPN;?h^J1yjk~N&M!hnWxg@hJkf>Y3%PZ1ST2OuXE7dqoptnu z`#4J(T-@ut{_(L_Oa;43TF=|-d)jjrnmOz)Nn|mKuR|{m)rmfQgo?E>clQHy=ISfn zpiH0GksL17@7JY6)n|{Jqn#tXZ@i9RYdO^Kh|ar2z=D{#6Bp|eg?4pjyzcc_a2So_ zR7ZS?M%b1u`HdOIOJSrbAGt*=E{G+FEtGZ<*jPePQ=meP6r-1SJcrR?yXP7xqTdUA ze1@{@0Z|kcBvxh*yPLzCG9}es9Z(ZOsDEC>{|)I;O{&b|SIw-02qMY(EJN{zl>Ln& z`+ITZ77{9UQ{KKx%Ndq6WQeI1W9f#BCh>xm?}uGWL_DJx3WrjTl$VVy`ojb!cet}8 zx=oCSces9#9_Ui8*&*n*xU>9%n(B*I68vzENRA0`ed6oKo*&t*Ok4GD*xar5<2>@l z-xD4hoikSZajcH{iu>LS(ei@~qZWZii=o}`xVj@l%Hyu8O|CnBW0wk3a=wwKH!69i z)EZMKV<>z20;wH0VRP79$#YJ(XClzc1Fnc)w&oX*!q%Z6u}P9}l#Tvk6KA7>FDQkB zF4LInTlY&8!f%QP_M}pDVr-cH9svOj^JO~^iZ`MMJFPBOs4U~--B>lkf>-igxs@GN zl{J|xQkx2spJ}1T_v_m@*grCIY=D8yFXGD;_aLe7fVkw1_Eo-_Q|J;SsmDEG*>TB5y@ILvb^J$08$i z4kuxDV4AY*d^%Rz+T0U!42gQ_zV^Pfm%WC#o)YvSWbO&qV(}p5Zfxal!Q}ukE7~gjo%Qm)NIF30gN}A3Xj#j?9sSvf|q!iWs4ej0%<7KxF-O!L2HsQ4P z%Ww7a70cc|vYp{i9nSgYaJX+D@VZxKCD5ud)>wJQdaR)JLBLC<4=lvJ!{O^vPRm|p zIM}NN#krk+C@OmTW5ADg;I}(UFTm%31n!_wt15Cqb-1LUP%hw2TvHcUO;dME3oTP; zYfD$4n4TWu4=~_)5jKPe-1<9xa)d5x1p~`LI(O;<2IJCnaC0`dRD;9306F681NpP6fcDx#(f|{n-Du$ZLE!6oz#bxyg+SQA!~cc+!Lpy8&J-yd zNs$mu5>;CpLkgmb+=B%7CI3tGr1*+B1mZ7##*xN=Pk>AO

QJGaO3beNt^Zj}NlM zbybHkoT5&O=5cYDESxj(0yUf)x>^UBAqfc9%}Q+V+dhuWw2EABs}E7?H>E;+ZEio_hK4~A0>3*cHSx86SjxsWPZdoPw8DP%Y))PVnk!N zC`ODzI+E$B(1lx--!E57UhdSBrWCqT*lb#3o(VVqa<~HBy%N)Ryd}T)U6~p&rQ(Yi z&uM!0{9;B8t;7+5J~M3=*Bm8pY?~U!k1t~au{sV4?;QJg1v5TRN|n5_rN|)eS1zxF zsrbS@4SSAFI$qzOyeGU?G^*W>7WYDJzb$c+S`N;9KQS_oxMyYrdOLH8*V(Y`@eAmR zp4-y(2};Iy{Xu?FM@4-u15xWvxpeP#?}Gh^35c-M5CrHilvKtfO?DpyRS@p?65g~yhn6=9f~&hP zJgVMG4vBK^Xf^PM-kDpq7vrZgZ#8DLge2!!%KIMMuuNKG~Th( zW6TVsu|T_MrJIKmm0ZTxgD@>fvX!&n<_S=$$CS$aXpI_@mwCH-3j;pWb#U?dMX^uO zfu&pwBFjou%RKZXkZ1=MW_b*`YquBtxuOWCs8maQxCM)FrS@B4!;eR?1K$U(^DLS0&AHv71T5w zr|2!T%KPfho_qyTz44cFWvxF9)egIru2F|REoW7@I_vZ)_N5Oi7edxKZW`;I`6DWq z6gmAEn&!6+rTX*MG4tzQJ&d~Z7U9_3X5mCWK!&F*te$vntzz#}*66kNVn z9{E*{tE=0}dZGmjT1;L3Vf3?lcn9=kJ?aL$K zNcgmmYy4o1pVDEDI=wmeoc&-s*XJ3o&*3&3U*+oCnLfYEewG<@F|TL!rQF+3GzlMh z5ljz}Xp3yDk*iZOEnDJ3E?p4nR6R+*a{59C%LmLM?1-v*Mi6b?*DL zQ+{7TM*YlZs=a*@SJwpJF$D-+T}NH^v`^42po(S|r*cne*`KzN!0ynQZKkyB zPumI|MJ>%!{SH|zIr_VI=)!iw3^u^EVmBX@C71GbaA2 z8v0+hn8BwqtY2jDr!wqcWVxp@oL^)Wr!w4MWUZ&NU-}C35ADU=`Gel!?=q}E^eJ}t z?|RsOu*IqUT@PpC53*&oJ;1YBbw>977H5%^t3`G@vW z{-IAP|Ijv?q~HC~{2@LLz2EgXOn#Sf-uQ#;^nCesu5tdsALrRz`(8-~R*GhrPZ4 literal 0 HcmV?d00001 diff --git a/labview-test-project/Error Tests/test Error Wrapping - No Execute On Error In.vi b/labview-test-project/Error Tests/test Error Wrapping - No Execute On Error In.vi new file mode 100644 index 0000000000000000000000000000000000000000..8f957ef92037b27f2d5a7acbe0ca6e92aa0f0fd0 GIT binary patch literal 14392 zcmeHubzD_V_wP9eq`Rc0Q;-Hh8o@(Li2~By9a4gTAkrco(xqY`3P?&xDAFj>rIb=4 z!kv8pAKyox`@X;X`+Yw5{&5$~Uf)@>)|xf3_nEV2j+VBTJU$K#O;r!6t}3T@2?i4g zhQUr$!(cE5fK33W1PM-h-p$R~jX}rK-NT*N!OPsi)ZHD(a~NR3FgO4(7={eEpu^B$ z=Kwz?6U;;eI2`;T4gdlClb&{Hzqn1>AYZCM_6R%k$1_lX2NI+Yv#LNWB`H5tzKhvO z{Cp$Qpr0;!Bo_7veK8n2<@1hQAfy8kJb_;OhE&Uivfc~t4%F)_pctTfY=-D3o3t`7 zZxRs~1bp`c?ST>PiHh|TsIA_5Q#YVV=}LeGWauCPLMXuCP|E?tfFbmds&bH2Q|AI7 zU{p}-uzzSc0#esRLh5h?=6`AfX+tJ}p*Z3&b9e;~^&p3ELRDKcH&ZuX22E2B8(uHl zqj)HQEr|W^r6^+rDsVWTfRL%MB|krppn$Lyj}Skf6_1#yg&>cW5TBSSzp#jq6`v>+ z_+dSivMw$Tw&tcDw$4rr3bt;R<{r*&zM#V69uNV((J{|?**e&oNnz@G0Pf+7Wo7GN z$?M=?_Rr=}NNA{tKo=j?2HM3aZ)0h0&tPlCpa@(rfa#>@>|kN(#&F)p7MfN+TPpvj zdhtLIP_H;ab^m);Pz*5izk)a#D@SCX(DJPn|U~)v=up1^|JYIbOffMq2*~)aqsi>T%+cPVVPN&Z%tKNnxL zHEryh{pRnzy7C#9n5WO8LVlc%39bF+2GRFNeEub2j>L23IqHHGdqer%l$J4f9<1j( z^s;=VzMPG_Sfu7&S}UC_e(9+e!5C)ybUuY1+yN2MkY^hpGm5)p)V^T8V6}w#gZ#w_ zf3&&yIkb7!e7O=G^&c{(aBrer?DrwOea;7Wg02i%kamogW$6-J|6Wa?Xw{XMd~%*T zYs}FR{r&Q{tMwGuGOH;&*%{Xh@?!|4qJ&w4}(nAavI)lKa% zbdwP578Av|FJi-27I65{^&97|rv_ZGkS2-DjR;i`c~9V#9Qaw!z7ab`idNBg$|RzB zh0o1ekyh_c35T2As!$3j$F4Wgv$F0LVf>3;;X`KuZ7y2lkPQfCdsw2PmUq0H6y2Xz4%z0jPmY5HOd4!LT3@ z3jj6%AO?_dAOI)`bPo?mAV~NZkU&pEBLcM<>Jn7#wLp&-rG0pTMip`djV0jl2*ANq zfIA&=SHMANaFauhC^+JhhaAoPh{qmsI5a9?4T2i46M&xwdC(#R(IJOx9r44J2@D|w z@?cmIDo30Sa4e8#JL2nrV}tzeA%{Wp9O|KC0&Pac3k?j=gW(?+{KEPEzSiPvu;ahy zp@M0XL}KuYCFT0(SC?@*8me`?b8#blN)6k9Z7_6a1iMnk24D03`1Si)kODy>{`eKh zqd~)tQ!v2)NlHt2WSWpzDx1m$_=|h8X{C9l|6~W%4K)kmztS2AjPL+P2qRpBt%1_R z{MrE__=Em|6-aB~x`q-R=Rpyq^jA6X@K+v^AJQ5Ox;=gpsO8_~f9gU2=>H4--_H}S zt*sHl)&XJJ&-+$URR0fdK2e*qx;r5u_bki$c#f4OF1Ir0vbqZCk=BO&DCm-0ghY5uwVIEFu!|Frl8 zfS}*K``3>BB?krc-!A{f-`^q1|KEkbr~hO5F-KJkg>hIv#Q%v7wf?E}{{{PBZiPQV5IO>ufogyq z46dkoK@(u`{asNL^~LYM{~f&nt|Dt@-7->bV*pzWvd88A>MO>ovKlGo~~& zr_84#JXm-GFYKfku<-cq81__smCSv-mTIbT-}MYmc8=@QH_=)4UtHvS?z3Mj$Y7}J zBN68grfSEmXmYoRr%B!u{WdSa)o7hcAin#eoheQ;eJm537OU+ZRixCW$9i{H5j)`l zmgOfBEhj;DY-fSH@9~~TRpQ?b=9QRe3d230m;U0S1U1q+C|G2M%V4!jKm^w&G0Dv! z%D#<3&>^vlW5#&ztkJorTu*<8D_6?ZaoABZOZGVd*xc6)wOh4WdW^PF_NwA+wm z!Z#j=5VfxwYooVD`Bws0a6bm7QHngH7i6@?Rtl+8pltB(pKD~cj7-HR{07^7PLX_@ zOOWPLv;%F@)pfGRjiw^CudU_F!!-@sc~0c8&@F7xEqRElxJJI)$5B5!=OLvjL8(^g z6_$AMqFPb%oCHnh7jKp4e7kph^e%4GG~#cEJW*X5$G4RHc-M_y{2I@0%_%?CwFlCg z1bg+&JB`Fx^x<#hKG>#(o1BT*Y#_YAc*!M&Qt(qH8IfNK_SOs4g`i6fbZI%K!k4S- z>!_>iFH&sNakqRhXfTT83H#A)5d4Gib;GzZ!PYjNi8sx|YmN`4t@vI>H4&is?qp>I zkSvV0dwr35-g2Ao{RcLMF*?S3MZF)$8Qf@yeD6ixNOPH+CEV<;;+yx|8e)`_zJ8fo zE~cot&gKQZtHAQo+f5DA`!40}=jExN29w)Xnh5*cFk_`{6?LAOq&FsY%Ip#i;uE7M zf3{lt;Nh2L1MhKmMYg^U9U;cn<_-%XPUC3gx-J^YVUbQr`n8(E@DZG`kb=QJ5GFXM6d5>F!-ADh^^%Kk5gBgZhQ^Z}E zTTIkude^Xc?N*0-o8upOj=XGoQLbLPsE{v&JASUDsdMR$o4sf6xlLLb3=etymCv0@ zL5-OO^MQ+BKegR>xti{*eQo+H>+AVj$-U0&-Sk208uQ_=x^!mLa>|Kv1Jf}~;d26PUp~)uor}#UXQ+DFc0m6CQ#@)q^!sF*Y50!NmkAF;!?Vekt zUw~`ClU)P;Pv6;NS5Ymm3nh5E?Ko_#b&ay>$rel7sD#Pj_=DS{c`atIa$BY@_?(Yv z)#^+!(-{v^s#srkf1e>1I+kuPQDA%JTEqMK=3%Sbd3$kN3>k0OmM@hXJz1kS2^+FG zQ`?}7qj68kmn%b=UB&JJFX6RWho|gpvxAonaU0}mb{tNgo;P@G@aTP-;0H}rx<~u6 zUA}cm_NV9k@t-s+=AU$WIZPXc=M;=#!H3_kSd@adzc;G&=x+M%NN3T0*;QN*MZKt) z^7oF9zC?`>Q!Yeb$SV~m#&1(N@gNMRW&)p{c8OFXT;jY%+)Zan+bYfEmHoFb;r`@Q zv5Hw~c8u%IR+z_%sFi^Be6Xgr0i180DyQN#^0R)_!tf zolDiJ_k%ZQNNOF}>mE2f^Ystw`=lPQSv^TWTH8~AllL;CNzCY?DOL>5^hl>Dj`!s- z*N6_r+waZaQ7U(_@iVojxUi7iE>id!z#r6>gsvP}c|#m&d4p0zA(qQd{49T%6)97Lg6z%6#@R?E$lm$XV>Pr#HQ(m$1{iRXTfbg;?c3$|>=z6~{O@c|z@jTZmQY zeXIM;*!tG>!@?C=Y3mQN(unJy+l71Q&$J$#6n1aJ8HgsEO3mSvR$7o>P@kRbcyoVO z8s{3(%PVOlZgq_sK@$VS>_hb}G$q+TIt_dp9#f4)5!QZgj7W)-^v`yoKQ&dK{bl|e z&DS8_J-l=Eu|t7{nbU!!cSqjT9lYH?+~C1UFvU3D55O?BuyA&A$2V41 zK{Dt#J3H9hdbnfj0SvrYy5arh%)#uZBj5nFY6S}>)O(r3O&^r>uM6~oCE@7RB=m;t z|ES8}8Uq|1w-osQ`!33Vu*U+EI|>ns@ABVXogx%`HPjBv;s2w144y}oqTVkd6hI@u z>s`b$c(o>fxTW#m-+zKe0{&Zn9W~Go6ym_;@ipC?t=&u=QCm0eWa_9*BU1+kq?5ac zo2R3tlZQK=s;QYC^86(R0k92);bqGUHf;VYljOGu4rd6e{ZNfCQS)er3v$F`Sa&-yADQjz&@-+fqFJy;(<*xp~QJK%+>Y<1pg67w0xsE?CYI7Kl$F=?Z2 zCq>~Db}E#~SL(%DsrIC~|$XT_JXdbM4*^ z)zx0k*eue-%?y@hK3fe_Nz?LqfxfSmO0jR6wpH|{ON^Tw^FOGLQj`}(FUbDbP1)jp zqAGRU;+CTee_A?b`T+k3WqhMeozOa54!$G&jbDuSy}izehDxkuB9YPS!ATKA!Zx^2 z62nbBd1k&V@17T(N!Gi^|5(&=i+jObL!dw*A+lMI$%>UJIRVL~*Yr8YKzX-uxIyOh z+p-kpR%L6l*Q#w(^2(X+*Vdgpf+|V)-wh^|N8JuvDtOneMNqjR; zf@O`{MVFFb?|e0OL^_`SNn65%E%e3RUCqSzVJo;6!xY0V74f7T_E8-Lvm&*s;c6!E z-J8+2dH6wjb2)`~X$tYyhT)nBtB`L?y#_ljS8vZX@HZ&jxA6o8-%lE=q{q?CRq=p1$sIcImvOFiqEN!!NP!PLi( zF}pncu4%l^l@%O!5u3|&D0<~Pp<9W>O(u#d9V?y1GMiB~*eM{( zY(kf$^drgcbzwn~iJt|5W~u>%eD|U> z{RTCZG?odKGcfW4hne-VR4v`?m{Qz*7aelH z#E?}BO{r&LsYk{UJp z@r^~Arty*oHYkh{O~e@AlM0K21y;bFfs~_+UTyef>S5Ra2fm2X8|4Dl4 zOHRY@6ov%j*B!6$O}IFwPk)r98PDkEBv0h5>dEBDuF9qFW^_z@nfd$_;_(izlSRYW z+YI!ZiV_?yaKzwxLpS}??u$t$<3=+n>Ew0<9*k08ypJOA&|l`oF$@l-e>#S}CQGxz z64R$9(Xly(9E;L8>uokEU@^<4*@*j$n%yaM08Om;Nc?+Lcs)pWkG4`f*rbY!tLT<6_ti684* zO6WZ&D=}QW$Z7SJ>(%tR6GIbU$749j9BLSGdc+e1FbOvB*qBoF1twW1f|?>GRCh8c z@JJAybl*Zp)cdLuO;gm)N%MNPpZv1z**C5}YSrg-hc`OL?{mnZGRXu zSSj)5#SpYA9qJ@IU$N3S-dQ~oAZA5(Hn_JCbIRk9u)?%!1)M_i(#G?9^|;a+_P93r zyv4c(J#kTy;1gs`L@`%x7!($E!iKZr0P2Y0?}@}+%adj zz%`ch>Kv%7{kT&^n3myTU|hIvtmwPEEv;z5wRvhkSc?gy7-vv6QA-a z(&6E0cZs+bq;#rX;&0-+yDx^~%oih@x zNnDUx#2tK}bAziOAZ`4z1l~-Kf89Dy-%I7ullki3B%eqa*)+Gk6=6NCQHaCl6i2+x zdAAyOAfBl;mQUX!v&mFg8Ao{8hNZA?Lr~Fauz6|NET3c~@b*$tqn&2A7$%lVZyU0`am0fl$1Be-0i+z#~THQ7$MuAs4ii!dQUEAwLSkL3%SiG&*a<@H~s7P;S zbhTSGm)H5;FOy#|bP*Y!V%vNwrzG~vK5gJq zFNVMpjmcM|07L={&kX6>_H&CpG+wH_mHD0gU6Jl$Z)Pq6@9QuQH<#s`k#7x&V1x5# zi+eq{g!|^12Ip7FI#XI2Kk>zGoHZatDza;@T8r%6f80lYO;7x$-iw4!*de~%;{>{gD)?a zv!5bLo^z}*rJilxI3=XI-A{l^FvXk1qVKSz=`c7pJwEI|A}aD!w7qS{giGM;xeM#k zds#HZWNAt`4ssLHKU_r^*X-MSYCi^$BI+;tkh+~2zcCSzpFWzuJx-g%*2!))Azdqr zJ;~3J_5?}HyvKH4NI1YbFtN|+R;IRpw={f{1=Z@a zXWYJr{8;Tjmu-{v1p>#nX|+_td97$XW~EIEf{JhaVv;UNw>z` zb3I`8gDEO~JUifQh=;+_lEgOMWtE&iH!}73Ju>y2cIYMS+Sz*yj22ICooiua&gW@t zCy$xh@x{-dd|sg8(#@;#Hr;DOSIjIHxG@N%1eglV`$T|?Hyus2Wnw#VMF;Z^P_y}A8d<0uqby=)%1Ie}r zukwU%@9@BO_oOWgFsG?zFBqS8dds~46HU2!&s>j;u5qdZZrIAmxo=n;xRNbDlWQOn zl(4f}VjGxDZg!A1_+tBeQqMv1q`JM|-Jr$2vl!nq3Qw(_Ntf<5$u80ZC^P7~tZ~1` zyLyj(lF$I;yP6*=^TwtR>xVXO0{t?)t=KgB%`=(xUD9W-TQ8E*y{-@6@5S5oR9jtt zkQM57Hz^-C2DfW(wY27S8qQNqSgVC>UG6gX=ITuabP4tR4lm-{qBNs(hUbDH)f zj%PWYxL-#9>0Iok%`sGmHDnjy0)QX(4~*y8cPki2QI#%p_ub-4rS08_gCo~?o3jJGMS zn>vPFKkS*s>h;@eBnxI|jPOtTFXDX2&XCCLQ6hJtjqAgf=*;j!1UpDZInd=*ZJ8Ua zqQArnqTiu^EUYy=7zGYo1~}Gz+WJIW<%uKIY%L@Dc=M{M0Zmb*XIC!;-rV;S=gqj+ znEct+DAG3tamGe>B}SM8@x`Pq61nC?OEwb=X?C1r7O|CMn!aN0^`F;TihG8O%c$Wl zu5mG;GL@}Su~!u>sM%IBHRxIFM~doC=aQuQ@x*qk&;!NR(|mXyx_I10ZzA4HC4gMx&18Rn_B_RaNB$r*ci*J+w`|EG=|Q z-K;G=KrsUYEEq8G4haj!2W&YX(MRCtG8vE)^$dZzm0JCtD|LRXus=q_ez(C-hDWSj+vi{@0qJgE$BnjtnEZ zy0eods9i=Aa*X@Sv1yP$t_rl*7M2N2K)cb>0Edq3fqg~PYYldQ|92D&75?;etVz{C zf`Vu=2wmM1vM_bjz9h6)`Cp>4QZ6YNELiH8ql|%1z@`6kgf;@UKdHdkQeAuRF$JQ! zs=YWK30I_f!W0H8Pd}%vi^2GV;tkpCen*7yt%pOeFx&d#XA=BhpPIm}e{uj@>FJEk z80N_co%4~Ds7ZT%&D#on!dj=cTP|a#g9C%MSMENk2f60gD?wj5TN*i*T&`}9K7?7s z@sx1jFo{yKw!eKe9X1TpyR;JZP39G{R>Eh1YR5G?Dro%xr&Mb%A#IJJXy_1*6(G+^&9AgyzH z|3UmIx*A96Z}_$>bh%v9oc!^v8rTP4M)>0OoWmw_KCTOAuVe=1izA8XNZ;5$dg`DS zAX3}y_dt5WNWtk0rHAfJX`WQa2($n6>y;QeQL+}5)&yMZHT%Mzw_hor^GtWz7J8JI zx>Ky+#TPF&N;mKK&(m(re>>f~P`;fj3bRSg>sJMHwl&%!+)U-*GI zNx9B=vZ^|#K=yKxkit;BrSAH?>TumZm zmLLrpN?}Mus2a4K^}=P>>foS$(cxO0!av1vw>WP`r|qHID=D8+`+(Jor%ux+e^4i5 zaj;|BP9$!W3N`SP>Xlv={5+%0^T3gwO|#&hH?Mr?_p= zZ_QG_eC5q_O|{ivC#%SX<-Ea0W$0LSXbscocgc7qpDxKO8{|*cRY%LS43f%wOgZWE z&i3g$x(ym`WE$0 z8B~$rXALMq2+3=xL#IOkAui~si9umN*ib!G$KV!9R-vM42?xzQ_bZFi^(alovR}=rC2J)lm%SWQv;S zeU9WD;AD*15k9A=sSTYw1%$4tr>St%C+HTcNHdEgxsRN}Pupm)V{~krBd74w_K6-+ zNBc;>T|o!6s|5LculBQz=xY~{$768ptC=Jlbta9U50^vBt!qp z7Q_EYhWU#O9Fav4)-SS*BN_HDvhpJt&M&gsBiS$Q#pwEj?DHRF8^6mi$$pn%wfsT$ z2V3kXzw2T5|3S9!y9|f+53-!!WqA3&%ZQ5qAba?`jF{mMveUoIsQ%Disz3B8)gRhM z8~3|E+CRj1+TwS;(+5B_-m5DPEak!|o_bBKQflAZAYyS5C6tJO0!yB;dE4tbOKw#{|jyCm literal 0 HcmV?d00001 diff --git a/labview-test-project/Error Tests/test Error Wrapping - Sets Error For Inner Error.vi b/labview-test-project/Error Tests/test Error Wrapping - Sets Error For Inner Error.vi new file mode 100644 index 0000000000000000000000000000000000000000..b6433064c02406e67f697d7d101de878e2741e62 GIT binary patch literal 12380 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 T*=;pA9C>sb`L6=NE5iQ*i(Kn? literal 0 HcmV?d00001 diff --git a/labview-test-project/rust-interop-test.lvlps b/labview-test-project/rust-interop-test.lvlps index 2a3a486..30e9ca3 100644 --- a/labview-test-project/rust-interop-test.lvlps +++ b/labview-test-project/rust-interop-test.lvlps @@ -1,2 +1,2 @@ [ProjectWindow_Data] -ProjectExplorer.ClassicPosition[String] = "37,769,915,1535" +ProjectExplorer.ClassicPosition[String] = "33,769,911,1535" From 1a68ce4b8577605a6d4f93dab018a6c551664aed Mon Sep 17 00:00:00 2001 From: James McNally Date: Tue, 17 Sep 2024 07:11:33 +0100 Subject: [PATCH 2/2] feat: Add Error Wrap with Return Status --- labview-interop/src/errors.rs | 4 +-- labview-interop/src/types/lv_errors.rs | 40 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/labview-interop/src/errors.rs b/labview-interop/src/errors.rs index 96406d8..4c0b4ed 100644 --- a/labview-interop/src/errors.rs +++ b/labview-interop/src/errors.rs @@ -415,8 +415,8 @@ pub enum InternalError { InvalidMgErrorCode = 542_006, } -impl From for LVStatusCode { - fn from(err: InternalError) -> LVStatusCode { +impl From<&InternalError> for LVStatusCode { + fn from(err: &InternalError) -> LVStatusCode { let err_i32: i32 = match err { InternalError::Misc => 542_000, InternalError::NoLabviewApi(_) => 542_001, diff --git a/labview-interop/src/types/lv_errors.rs b/labview-interop/src/types/lv_errors.rs index bcee528..337e38e 100644 --- a/labview-interop/src/types/lv_errors.rs +++ b/labview-interop/src/types/lv_errors.rs @@ -94,6 +94,46 @@ impl ErrorClusterPtr<'_> { } } } + + /// Wrap the provided function in error handling to match LabVIEW semantics. + /// + /// i.e. no execution on error in, convert return errors into error cluster. + /// + /// This version returns the LabVIEW status code of the error. + /// To return a different value, see [`ErrorClusterPtr::wrap_function`]. + /// + /// ## Parameters + /// + /// - `function` - The function to wrap. This is intended to be a closure for + /// easy use. + /// + /// ## Example + /// + /// ```rust + /// use labview_interop::types::{ErrorClusterPtr, LVStatusCode}; + /// use labview_interop::errors::LVInteropError; + /// use labview_interop::types::LStrHandle; + /// + /// #[no_mangle] + /// pub extern "C" fn example_function(mut error_cluster: ErrorClusterPtr, mut string_input: LStrHandle) -> LVStatusCode { + /// error_cluster.wrap_return_status(|| -> Result<(), LVInteropError> { + /// // Do some work + /// string_input.set_str("Hello World")?; + /// Ok(()) + /// + /// }) + /// } + /// ``` + pub fn wrap_return_status std::result::Result<(), E>>( + &mut self, + function: F, + ) -> LVStatusCode { + if self.is_err() { + return self.code; + } + self.wrap_function((), function); + self.code + } } #[cfg(feature = "link")]