autosway 0.5.0

Automation program
Documentation
use std::{str::FromStr, sync::Arc};

use super::*;
use request::{Client, Response};
use reqwest::blocking as request;

#[derive(PartialEq, Eq)]
pub enum RequestType {
    Get,
    Head,
    Post(String),
    Put(String),
    Patch(String),
    Delete(String),
}

pub struct NetRequest(String, RequestType);

impl NetRequest {
    #[allow(dead_code)]
    pub fn ensure_type(&self, t: RequestType) -> LuaResult<()> {
        if self.1 != t {
            Err(LuaError::runtime("Incorrect request type"))
        } else {
            Ok(())
        }
    }

    pub fn request(&self) -> LuaResult<Response> {
        let uri = match reqwest::Url::from_str(&self.0) {
            Ok(u) => u,
            Err(e) => return Err(LuaError::external(Arc::new(e))),
        };

        let client = Client::new();
        match &self.1 {
            RequestType::Get => match client.get(uri).send() {
                Ok(r) => Ok(r),
                Err(e) => Err(LuaError::external(Arc::new(e))),
            },
            RequestType::Head => match client.head(uri).send() {
                Ok(r) => Ok(r),
                Err(e) => Err(LuaError::external(Arc::new(e))),
            },
            RequestType::Post(body) => match client.post(uri).body(body.clone()).send() {
                Ok(r) => Ok(r),
                Err(e) => Err(LuaError::external(Arc::new(e))),
            },
            RequestType::Put(body) => match client.put(uri).body(body.clone()).send() {
                Ok(r) => Ok(r),
                Err(e) => Err(LuaError::external(Arc::new(e))),
            },
            RequestType::Patch(body) => match client.patch(uri).body(body.clone()).send() {
                Ok(r) => Ok(r),
                Err(e) => Err(LuaError::external(Arc::new(e))),
            },
            RequestType::Delete(body) => match client.delete(uri).body(body.clone()).send() {
                Ok(r) => Ok(r),
                Err(e) => Err(LuaError::external(Arc::new(e))),
            },
        }
    }
}

impl LuaUserData for NetRequest {
    fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
        methods.add_method("text", |_, this, _: ()| {
            let response = this.request()?;

            match response.text() {
                Ok(text) => Ok(text),
                Err(e) => Err(LuaError::external(Arc::new(e))),
            }
        });

        methods.add_method("json", |_, this, _: ()| {
            let response = this.request()?;

            match response.json::<serde_json::Value>() {
                Ok(json) => Ok(json.to_string()),
                Err(e) => Err(LuaError::external(Arc::new(e))),
            }
        });

        methods.add_method("status", |_, this, _: ()| {
            let response = this.request()?;
            Ok(response.status().to_string())
        });

        methods.add_method("headers", |lua, this, _: ()| {
            let response = this.request()?;

            let table = lua.create_table()?;
            for (key, value) in response.headers() {
                let str = match value.to_str() {
                    Ok(s) => s.to_string(),
                    Err(e) => return Err(LuaError::external(Arc::new(e))),
                };
                table.set(key.to_string(), str)?;
            }

            Ok(table)
        });
    }
}

pub struct Net;
impl Module for Net {
    fn load(&self, state: &mut State) -> Result<(), LuaError> {
        let module = state.lua.create_table()?;
        let http = state.lua.create_table()?;

        http.set(
            "get",
            state
                .lua
                .create_function(|_, url: String| Ok(NetRequest(url, RequestType::Get)))?,
        )?;

        http.set(
            "head",
            state.lua.create_function(|_, url: String| {
                NetRequest(url, RequestType::Head).request()?;
                Ok(())
            })?,
        )?;

        http.set(
            "post",
            state
                .lua
                .create_function(|_, (url, body): (String, String)| {
                    Ok(NetRequest(url, RequestType::Post(body)))
                })?,
        )?;

        http.set(
            "put",
            state
                .lua
                .create_function(|_, (url, body): (String, String)| {
                    Ok(NetRequest(url, RequestType::Put(body)))
                })?,
        )?;

        http.set(
            "patch",
            state
                .lua
                .create_function(|_, (url, body): (String, String)| {
                    Ok(NetRequest(url, RequestType::Patch(body)))
                })?,
        )?;

        http.set(
            "delete",
            state
                .lua
                .create_function(|_, (url, body): (String, String)| {
                    Ok(NetRequest(url, RequestType::Delete(body)))
                })?,
        )?;

        module.set("http", http)?;

        create_module(&state.lua, "autosway.net", module)?;

        Ok(())
    }
}