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