facebook_api_rs 0.1.2

A Rust client library for the Facebook Graph API v23.0, with full support for both native and WebAssembly (WASM) environments
Documentation
use crate::prelude::errors::{ClientErr, FacebookAPiError};
use crate::prelude::HttpConnection;
use serde::de::DeserializeOwned;
use serde::Deserialize;
use serde_json::{json, Value};
use std::fmt::Debug;

pub struct BatchApi {
    pub base_url: String,
    pub page_access_token: String,
    pub page_id: String,
}

impl BatchApi {
    pub fn new(base_url: String, page_access_token: String, page_id: String) -> Self {
        BatchApi {
            base_url,
            page_access_token,
            page_id,
        }
    }

    pub async fn request(
        self,
        batch_items: BatchItems,
    ) -> Result<Vec<BatchResponseBody>, ClientErr> {
        let batch = serde_json::to_string(&batch_items.data).unwrap();

        let url = self.base_url
            + "?batch="
            + &batch
            + "&access_token="
            + &self.page_access_token
            + "&include_headers=false";

        let resp =
            HttpConnection::batch_post::<Vec<BatchResponseBody>, String>(url, "".to_string())
                .await?;
        Ok(resp)
    }

    pub async fn request_with_type<T>(
        self,
        batch_items: BatchItems,
    ) -> Result<Vec<BatchResponseBodyWithType<T>>, ClientErr>
    where
        T: DeserializeOwned,
    {
        let batch = serde_json::to_string(&batch_items.data).unwrap();

        let url = self.base_url
            + "?batch="
            + &batch
            + "&access_token="
            + &self.page_access_token
            + "&include_headers=false";

        let resp: Vec<BatchResponseBody> =
            HttpConnection::batch_post::<Vec<BatchResponseBody>, String>(url, "".to_string())
                .await?;

        let mut resp_body: Vec<BatchResponseBodyWithType<T>> = Vec::new();

        for body in resp {
            if let Some(data) = body.body {
                if body.code == 200 {
                    let data: T = serde_json::from_str(&data.as_str())?;

                    resp_body.push(BatchResponseBodyWithType {
                        code: body.code,
                        body: Some(data),
                        error: None,
                    })
                } else {
                    let data: FacebookAPiError = serde_json::from_str(&data.as_str())?;

                    resp_body.push(BatchResponseBodyWithType {
                        code: body.code,
                        body: None,
                        error: Some(data),
                    })
                }
            } else {
                resp_body.push(BatchResponseBodyWithType {
                    code: body.code,
                    body: None,
                    error: None,
                })
            }
        }
        Ok(resp_body)
    }
}

#[derive(Deserialize, Debug, Clone, Default)]
pub struct BatchItems {
    pub data: Vec<Value>,
}

impl BatchItems {
    pub fn add_batch_item_with_body(
        mut self,
        method: &str,
        body: String,
        relative_url: &str,
    ) -> Self {
        let data = json!(
            {
                "method": method.to_uppercase(),
               "relative_url":relative_url,
                "body": body
            }
        );

        self.data.push(data);
        self
    }

    pub fn add_batch_item_with_body_access_token(
        mut self,
        method: &str,
        body: String,
        relative_url: &str,
        access_token: String,
    ) -> Self {
        let data = json!(
            {
                "method": method.to_uppercase(),
               "relative_url":relative_url.to_owned() + "?access_token=" + &access_token,
                "body": body
            }
        );
        self.data.push(data);
        self
    }

    pub fn add_batch_item_without_body(mut self, method: &str, relative_url: &str) -> Self {
        let data = json!(
            {
                "method": method.to_uppercase(),
               "relative_url":relative_url,
            }
        );
        self.data.push(data);
        self
    }

    pub fn add_batch_item_with_access_token(
        mut self,
        method: &str,
        relative_url: &str,
        access_token: String,
    ) -> Self {
        let data = json!(
            {
                "method": method.to_uppercase(),
               "relative_url":relative_url.to_owned() + "?access_token=" + &access_token,
            }
        );
        self.data.push(data);
        self
    }
}

#[derive(Deserialize, Debug, Clone)]
pub struct BatchResponseBody {
    pub code: u64,
    pub body: Option<String>,
}

#[derive(Deserialize, Debug, Clone)]
pub struct BatchResponseBodyWithType<T> {
    pub code: u64,
    pub body: Option<T>,
    pub error: Option<FacebookAPiError>,
}