aboutsummaryrefslogtreecommitdiff
path: root/.config/awesome/quarrel/native/src/util.rs
diff options
context:
space:
mode:
Diffstat (limited to '.config/awesome/quarrel/native/src/util.rs')
-rw-r--r--.config/awesome/quarrel/native/src/util.rs101
1 files changed, 101 insertions, 0 deletions
diff --git a/.config/awesome/quarrel/native/src/util.rs b/.config/awesome/quarrel/native/src/util.rs
new file mode 100644
index 0000000..85a2574
--- /dev/null
+++ b/.config/awesome/quarrel/native/src/util.rs
@@ -0,0 +1,101 @@
+use std::{
+ cell::RefCell,
+ fs::File,
+ fs::OpenOptions,
+ io::{
+ Read,
+ Seek,
+ Write
+ },
+ rc::Rc,
+ str::FromStr,
+};
+
+use html_escape::decode_html_entities_to_string;
+use mlua::prelude::*;
+use serde::Serialize;
+
+pub fn decode_html(_: &Lua, string: String) -> LuaResult<String> {
+ let mut output = String::new();
+ decode_html_entities_to_string(string, &mut output);
+ Ok(output)
+}
+
+enum ReadMode {
+ Line,
+ Number,
+ All,
+}
+
+impl FromStr for ReadMode {
+ type Err = ();
+
+ fn from_str(value: &str) -> Result<Self, Self::Err> {
+ Ok(match value {
+ "l" => Self::Line,
+ "n" => Self::Number,
+ _ => Self::All,
+ })
+ }
+}
+
+#[derive(Serialize)]
+#[serde(untagged)]
+enum StringOrNumber {
+ String(String),
+ Number(u64),
+}
+
+pub struct FileHandle(Rc<RefCell<File>>);
+
+impl LuaUserData for FileHandle {
+ fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
+ methods.add_method("read", |lua, this: &FileHandle, mode: String| {
+ let content = this.read()?;
+ Ok(lua.to_value(&match ReadMode::from_str(&mode).unwrap() {
+ ReadMode::Line => StringOrNumber::String(
+ content
+ .lines()
+ .next()
+ .map_or_else(String::new, |slice| slice.trim().to_owned()),
+ ),
+ ReadMode::Number => StringOrNumber::Number(
+ content.trim().parse::<u64>().map_err(LuaError::external)?,
+ ),
+ ReadMode::All => StringOrNumber::String(content),
+ }))
+ });
+ methods.add_method("write", |_, this: &FileHandle, content: String| {
+ this.write(content.as_bytes())
+ });
+ methods.add_method("lines", |_, this: &FileHandle, (): ()| {
+ Ok(this
+ .read()?
+ .lines()
+ .map(ToOwned::to_owned)
+ .collect::<Vec<String>>())
+ });
+ methods.add_method("rewind", |_, this: &FileHandle, (): ()| this.rewind());
+ }
+}
+
+impl FileHandle {
+ pub fn new(_: &Lua, path: String) -> LuaResult<Self> {
+ Ok(Self(Rc::new(RefCell::new(File::open(path)?))))
+ // Ok(Self(Rc::new(RefCell::new(OpenOptions::new().write(true).read(true).open(path)?))))
+ }
+
+ fn read(&self) -> LuaResult<String> {
+ let mut content = String::new();
+ self.0.borrow_mut().read_to_string(&mut content)?;
+ Ok(content)
+ }
+
+ fn rewind(&self) -> LuaResult<()> {
+ self.0.borrow_mut().rewind().map_err(LuaError::external)
+ }
+
+ fn write(&self, buf: &[u8]) -> LuaResult<usize> {
+ self.0.borrow_mut().write(buf).map_err(LuaError::external)
+ }
+}