Skip to main content

eric_sdk/
response.rs

1use crate::error_code::ErrorCode;
2use anyhow::anyhow;
3use eric_bindings::{
4    EricReturnBufferApi, EricRueckgabepufferErzeugen, EricRueckgabepufferFreigeben,
5    EricRueckgabepufferInhalt,
6};
7use std::ffi::CStr;
8use tracing::debug;
9
10/// Shared payload for `EricResponse` and `EricError` returned by ERiC API
11/// calls.
12#[derive(Debug, Clone)]
13pub struct EricApiPayload {
14    /// The response when validating an XML file.
15    pub validation_response: String,
16    /// The response when an XML file is sent to the tax authorities.
17    pub server_response: String,
18}
19
20impl EricApiPayload {
21    pub fn new(validation_response: String, server_response: String) -> Self {
22        Self {
23            validation_response,
24            server_response,
25        }
26    }
27}
28
29/// A structure which summarizes the response from the Eric instance.
30///
31/// Usually returned payload can be ignored when the API call was successful and
32/// looks like this:
33/// ```xml
34/// <?xml version="1.0" encoding="UTF-8"?>
35/// <EricBearbeiteVorgang xmlns="http://www.elster.de/EricXML/1.1/EricBearbeiteVorgang">
36///     <Erfolg/>
37/// </EricBearbeiteVorgang>
38/// ```
39#[derive(Debug)]
40pub struct EricResponse {
41    /// XML payload returned by ERiC.
42    pub payload: EricApiPayload,
43}
44
45impl EricResponse {
46    pub fn new(payload: EricApiPayload) -> Self {
47        Self { payload }
48    }
49
50    pub fn validation_response(&self) -> &str {
51        self.payload.validation_response.as_str()
52    }
53
54    pub fn server_response(&self) -> &str {
55        self.payload.server_response.as_str()
56    }
57}
58
59/// A wrapper type for the response buffer of the Eric instance.
60pub struct ResponseBuffer {
61    ctx: *mut EricReturnBufferApi,
62}
63
64impl ResponseBuffer {
65    pub fn new() -> Result<Self, anyhow::Error> {
66        let response_buffer = unsafe { EricRueckgabepufferErzeugen() };
67
68        if response_buffer.is_null() {
69            return Err(anyhow!("EricRueckgabepufferErzeugen returned null"));
70        }
71
72        Ok(ResponseBuffer {
73            ctx: response_buffer,
74        })
75    }
76
77    pub fn as_ptr(&self) -> *mut EricReturnBufferApi {
78        self.ctx
79    }
80
81    pub fn read(&self) -> Result<&str, anyhow::Error> {
82        let buffer = unsafe {
83            let ptr = EricRueckgabepufferInhalt(self.ctx);
84
85            if ptr.is_null() {
86                return Err(anyhow!("EricRueckgabepufferInhalt returned null"));
87            }
88
89            CStr::from_ptr(ptr)
90        };
91
92        Ok(buffer.to_str()?)
93    }
94}
95
96impl Drop for ResponseBuffer {
97    fn drop(&mut self) {
98        debug!("Cleaning up response buffer");
99
100        let error_code = unsafe { EricRueckgabepufferFreigeben(self.ctx) };
101
102        match error_code {
103            x if x == ErrorCode::ERIC_OK as i32 => (),
104            error_code => panic!("Can't drop reponse buffer: {}", error_code),
105        }
106    }
107}