hdbconnect_impl/protocol/parts/
execution_result.rs1use std::vec::IntoIter;
2
3use crate::{HdbResult, ServerError};
4use byteorder::{LittleEndian, ReadBytesExt};
5
6#[derive(Clone, Debug, PartialEq, Eq)]
8pub enum ExecutionResult {
9 RowsAffected(usize),
11 SuccessNoInfo, Failure(Option<ServerError>), ExtraFailure(ServerError),
17}
18impl ExecutionResult {
19 #[must_use]
21 pub fn is_failure(&self) -> bool {
22 matches!(self, Self::Failure(_))
23 }
24 #[must_use]
26 pub fn is_rows_affected(&self) -> bool {
27 matches!(self, Self::RowsAffected(_))
28 }
29}
30
31impl std::fmt::Display for ExecutionResult {
32 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
33 match *self {
34 Self::RowsAffected(count) => writeln!(fmt, "Number of affected rows: {count}, ")?,
35 Self::SuccessNoInfo => writeln!(
36 fmt,
37 "Command successfully executed but number of affected rows cannot be determined"
38 )?,
39 Self::Failure(Some(ref server_error)) => writeln!(
40 fmt,
41 "Execution of statement or processing of row has failed with {server_error:?}",
42 )?,
43 Self::Failure(None) => writeln!(
44 fmt,
45 "Execution of statement or processing of row has failed"
46 )?,
47 Self::ExtraFailure(ref server_error) => {
48 writeln!(fmt, "Extra server error was reported: {server_error:?}",)?;
49 }
50 }
51 Ok(())
52 }
53}
54
55#[derive(Debug)]
56pub struct ExecutionResults(Vec<ExecutionResult>);
58impl std::fmt::Display for ExecutionResults {
59 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
60 for execution_result in &self.0 {
61 std::fmt::Display::fmt(&execution_result, fmt)?;
62 }
63 Ok(())
64 }
65}
66impl ExecutionResults {
67 pub(crate) fn parse(count: usize, rdr: &mut dyn std::io::Read) -> HdbResult<Self> {
68 let mut vec = Vec::<ExecutionResult>::with_capacity(count);
69 for _ in 0..count {
70 match rdr.read_i32::<LittleEndian>()? {
71 -2 => vec.push(ExecutionResult::SuccessNoInfo),
72 -3 => vec.push(ExecutionResult::Failure(None)),
73 #[allow(clippy::cast_sign_loss)]
74 i => vec.push(ExecutionResult::RowsAffected(i as usize)),
75 }
76 }
77 Ok(Self(vec))
78 }
79
80 pub(crate) fn mix_in_server_errors(&mut self, mut err_iter: IntoIter<ServerError>) {
81 for execution_result in &mut self.0 {
82 if let ExecutionResult::Failure(_) = *execution_result {
83 *execution_result = ExecutionResult::Failure(err_iter.next());
84 }
85 }
86 for e in err_iter {
87 warn!(
88 "Reply::handle_db_error(): \
89 found more server_errors than instances of ExecutionResult::Failure"
90 );
91 self.0.push(ExecutionResult::Failure(Some(e)));
92 }
93 }
94}
95
96impl std::iter::IntoIterator for ExecutionResults {
97 type Item = ExecutionResult;
98 type IntoIter = std::vec::IntoIter<ExecutionResult>;
99 fn into_iter(self) -> Self::IntoIter {
100 self.0.into_iter()
101 }
102}
103impl<I: std::slice::SliceIndex<[ExecutionResult]>> std::ops::Index<I> for ExecutionResults {
104 type Output = I::Output;
105 fn index(&self, index: I) -> &Self::Output {
106 &self.0[index]
107 }
108}