haproxy_api/
channel.rs

1use std::ops::Deref;
2
3use mlua::{FromLua, IntoLua, Lua, Result, String as LuaString, Table, TableExt, Value};
4
5/// The "Channel" class contains all functions to manipulate channels.
6///
7/// Please refer to HAProxy documentation to get more information.
8#[derive(Clone)]
9pub struct Channel<'lua> {
10    lua: &'lua Lua,
11    class: Table<'lua>,
12}
13
14impl<'lua> Channel<'lua> {
15    /// Copies the string string at the end of incoming data of the channel buffer.
16    /// Returns the copied length on success or -1 if data cannot be copied.
17    #[inline]
18    pub fn append(&self, data: impl AsRef<[u8]>) -> Result<isize> {
19        let data = self.lua.create_string(data.as_ref())?;
20        self.class.call_method("append", data)
21    }
22
23    /// Returns `length` bytes of incoming data from the channel buffer, starting at the `offset`.
24    /// The data are not removed from the buffer.
25    #[inline]
26    pub fn data(
27        &self,
28        offset: Option<isize>,
29        length: Option<isize>,
30    ) -> Result<Option<LuaString<'lua>>> {
31        let offset = offset.unwrap_or(0);
32        match length {
33            Some(length) => self.class.call_method("data", (offset, length)),
34            None => self.class.call_method("data", offset),
35        }
36    }
37
38    /// Forwards `length` bytes of data from the channel buffer.
39    /// Returns the amount of data forwarded and must not be called from an action to avoid yielding.
40    #[inline]
41    pub fn forward(&self, length: usize) -> Result<usize> {
42        self.class.call_method("forward", length)
43    }
44
45    /// Returns the length of incoming data in the channel buffer.
46    #[inline]
47    pub fn input(&self) -> Result<usize> {
48        self.class.call_method("input", ())
49    }
50
51    /// Copies the `data` at the `offset` in incoming data of the channel buffer.
52    /// Returns the copied length on success or -1 if data cannot be copied.
53    ///
54    /// By default, if no `offset` is provided, the string is copied in front of incoming data.
55    /// A positive `offset` is relative to the beginning of incoming data of the channel buffer while negative offset is relative to their end.
56    #[inline]
57    pub fn insert(&self, data: impl AsRef<[u8]>, offset: Option<isize>) -> Result<isize> {
58        let data = self.lua.create_string(data.as_ref())?;
59        let offset = offset.unwrap_or(0);
60        self.class.call_method::<_, isize>("insert", (data, offset))
61    }
62
63    /// Returns true if the channel buffer is full.
64    #[inline]
65    pub fn is_full(&self) -> Result<bool> {
66        self.class.call_method("is_full", ())
67    }
68
69    /// Returns true if the channel is the response one.
70    #[inline]
71    pub fn is_resp(&self) -> Result<bool> {
72        self.class.call_method("is_resp", ())
73    }
74
75    /// Parses `length` bytes of incoming data of the channel buffer, starting at `offset`,
76    /// and returns the first line found, including the `\n`.
77    ///
78    /// The data are not removed from the buffer. If no line is found, all data are returned.
79    #[inline]
80    pub fn line(
81        &self,
82        offset: Option<isize>,
83        length: Option<isize>,
84    ) -> Result<Option<LuaString<'lua>>> {
85        let offset = offset.unwrap_or(0);
86        match length {
87            Some(length) => self.class.call_method("line", (offset, length)),
88            None => self.class.call_method("line", offset),
89        }
90    }
91
92    /// Returns true if the channel may still receive data.
93    #[inline]
94    pub fn may_recv(&self) -> Result<bool> {
95        self.class.call_method("may_recv", ())
96    }
97
98    /// Returns the length of outgoing data of the channel buffer.
99    #[inline]
100    pub fn output(&self) -> Result<usize> {
101        self.class.call_method("output", ())
102    }
103
104    /// Copies the `data` in front of incoming data of the channel buffer.
105    /// Returns the copied length on success or -1 if data cannot be copied.
106    #[inline]
107    pub fn prepend(&self, data: impl AsRef<[u8]>) -> Result<isize> {
108        let data = self.lua.create_string(data.as_ref())?;
109        self.class.call_method::<_, isize>("prepend", data)
110    }
111
112    /// Removes `length` bytes of incoming data of the channel buffer, starting at `offset`.
113    /// Returns number of bytes removed on success.
114    #[inline]
115    pub fn remove(&self, offset: Option<isize>, length: Option<usize>) -> Result<isize> {
116        let offset = offset.unwrap_or(0);
117        match length {
118            Some(length) => self.class.call_method("remove", (offset, length)),
119            None => self.class.call_method("remove", offset),
120        }
121    }
122
123    /// Requires immediate send of the `data`.
124    /// It means the `data` is copied at the beginning of incoming data of the channel buffer and immediately forwarded.
125    #[inline]
126    pub fn send(&self, data: impl AsRef<[u8]>) -> Result<isize> {
127        let data = self.lua.create_string(data.as_ref())?;
128        self.class.call_method("send", data)
129    }
130
131    /// Replaces `length` bytes of incoming data of the channel buffer, starting at `offset`, by the new `data`.
132    /// Returns the copied length on success or -1 if data cannot be copied.
133    #[inline]
134    pub fn set(
135        &self,
136        data: impl AsRef<[u8]>,
137        offset: Option<isize>,
138        length: Option<usize>,
139    ) -> Result<isize> {
140        let data = self.lua.create_string(data.as_ref())?;
141        let offset = offset.unwrap_or(0);
142        match length {
143            Some(length) => self.class.call_method("set", (data, offset, length)),
144            None => self.class.call_method("set", (data, offset)),
145        }
146    }
147}
148
149impl<'lua> FromLua<'lua> for Channel<'lua> {
150    #[inline]
151    fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
152        let class = Table::from_lua(value, lua)?;
153        Ok(Channel { lua, class })
154    }
155}
156
157impl<'lua> IntoLua<'lua> for Channel<'lua> {
158    #[inline]
159    fn into_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
160        Ok(Value::Table(self.class))
161    }
162}
163
164impl<'lua> Deref for Channel<'lua> {
165    type Target = Table<'lua>;
166
167    #[inline]
168    fn deref(&self) -> &Self::Target {
169        &self.class
170    }
171}