cortical-io 0.1.14

Cortical.io API client
Documentation
use std::error::Error;

use crate::{CompareResponse, CreateCategoryFilterRequest, CreateCategoryFilterResponse, Fingerprint, GetTermsContextsRequest, GetTermsContextsResponse, GetTermsRequest, GetTermsResponse, GetTermsSimilarTermsRequest, LanguageResponse, PosType, Retina, TextEnvelope, TextSlice, TextSliceRequest};

pub struct Cortical {
    pub client: reqwest::Client,
    pub base_url: String,
}

impl Cortical {
    pub fn new() -> Cortical {
        Cortical {
            client: reqwest::Client::new(),
            base_url: std::env::var("CORTICAL_API_URL").unwrap_or("https://languages.cortical.io".to_string()),
        }
    }

    pub async fn get_retinas(&self) -> Result<Vec<Retina>, Box<dyn Error>> {
        let response =
            self.client
                .get(format!("{}{}", &self.base_url, "/rest/retinas"))
                .send()
                .await?;

        Ok(
            response
                .json()
                .await?
        )
    }

    pub async fn get_text_analysis(
        &self,
        text: &str,
        retina_name: Option<&str>,
    ) -> Result<Vec<Fingerprint>, Box<dyn Error>> {
        let retina_name = retina_name.unwrap_or("en_general");

        let response =
            self.client
                .post(format!("{}/rest/text?retina_name={}", &self.base_url, retina_name))
                .header("Accept", "application/json")
                .header("Referer", "")
                .header("Content-Type", "application/json")
                .body(text.to_string())
                .send()
                .await?;

        Ok(
            response
                .json()
                .await?
        )
    }

    pub async fn get_text_keywords(
        &self,
        text: &str,
        retina_name: Option<&str>,
    ) -> Result<Vec<String>, Box<dyn Error>> {
        let retina_name = retina_name.unwrap_or("en_general");

        let response =
            self.client
                .post(format!("{}/rest/text/keywords?retina_name={}", &self.base_url, retina_name))
                .header("Accept", "application/json")
                .header("Referer", "")
                .header("Content-Type", "text/plain;charset=UTF-8")
                .body(text.to_string())
                .send()
                .await?;

        Ok(
            response
                .json()
                .await?
        )
    }

    pub async fn get_text_slices(
        &self,
        text: &str,
        params: Option<TextSliceRequest>,
    ) -> Result<Vec<TextSlice>, Box<dyn Error>> {
        let params = params.unwrap_or_default();

        let response =
            self.client
                .post(
                    format!(
                        "{}/rest/text/slices?retina_name={}&start_index={}&max_results={}&get_fingerprint={}",
                        &self.base_url,
                        params.retina_name,
                        params.start_index,
                        params.max_results,
                        params.get_fingerprint
                    )
                )
                .header("Accept", "application/json")
                .header("Referer", "")
                .header("Content-Type", "application/json")
                .body(text.to_string())
                .send()
                .await?;

        Ok(
            response
                .json()
                .await?
        )
    }

    pub async fn get_text_detect_language(
        &self,
        text: &str,
    ) -> Result<LanguageResponse, Box<dyn Error>> {
        let response =
            self.client
                .post(format!("{}/rest/text/detect_language", &self.base_url))
                .header("Accept", "application/json")
                .header("Referer", "")
                .header("Content-Type", "application/json")
                .body(text.to_string())
                .send()
                .await?;

        Ok(
            response
                .json()
                .await?
        )
    }

    pub async fn create_category_filter(
        &self,
        positive_examples: Vec<String>,
        negative_examples: Vec<String>,
        retina_name: Option<&str>,
    ) -> Result<CreateCategoryFilterResponse, Box<dyn Error>> {
        let retina_name = retina_name.unwrap_or("en_general");

        let positive_examples = positive_examples
            .into_iter()
            .map(|text| TextEnvelope { text })
            .collect();

        let negative_examples = negative_examples
            .into_iter()
            .map(|text| TextEnvelope { text })
            .collect();

        let request = CreateCategoryFilterRequest {
            category_name: None,
            positive_examples,
            negative_examples,
        };

        Ok(
            self.client
                .post(
                    format!(
                        "{}/rest/classify/create_category_filter?retina_name={}&filter_name={}",
                        &self.base_url,
                        retina_name,
                        "filter_name"
                    )
                )
                .header("Accept", "application/json")
                .header("Referer", "")
                .header("Content-Type", "application/json")
                .body(serde_json::to_string(&request)?)
                .send()
                .await?
                .json()
                .await?
        )
    }

    pub async fn get_compare(
        &self,
        (text1, text2): (&str, &str),
        retina_name: Option<&str>,
    ) -> Result<CompareResponse, Box<dyn Error>> {
        let retina_name = retina_name.unwrap_or("en_general");

        Ok(
            self.client
                .post(format!("{}/rest/compare?retina_name={}", &self.base_url, retina_name))
                .header("Accept", "application/json")
                .header("Referer", "")
                .header("Content-Type", "application/json")
                .body(
                    serde_json::to_string(
                        &vec![
                            TextEnvelope::new(text1),
                            TextEnvelope::new(text2),
                        ]
                    )?
                )
                .send()
                .await?
                .json()
                .await?
        )
    }

    pub async fn get_terms(
        &self,
        retina_name: Option<&str>,
        term: Option<&str>,
        get_fingerpint: Option<bool>,
        start_index: Option<u32>,
        max_results: Option<u32>,
    ) -> Result<GetTermsResponse, Box<dyn Error>> {
        let retina_name = retina_name.unwrap_or("en_general");

        let query =
            GetTermsRequest {
                retina_name: retina_name.to_string(),
                term: term.map(|term| term.to_string()),
                start_index,
                max_results,
                get_fingerprint: get_fingerpint.unwrap_or(false),
            };

        let response =
            self.client
                .get(format!("{}/rest/terms", &self.base_url))
                .header("Accept", "application/json")
                .header("Referer", "")
                .header("Content-Type", "application/json")
                .query(&query)
                .send()
                .await?;

        Ok(
            response
                .json()
                .await?
        )
    }

    pub async fn get_terms_contexts(
        &self,
        term: &str,
        retina_name: Option<&str>,
        get_fingerpint: Option<bool>,
        start_index: Option<u32>,
        max_results: Option<u32>,
    ) -> Result<GetTermsContextsResponse, Box<dyn Error>> {
        let retina_name = retina_name.unwrap_or("en_general");

        let query =
            GetTermsContextsRequest {
                retina_name: retina_name.to_string(),
                term: term.to_string(),
                start_index,
                max_results,
                get_fingerprint: get_fingerpint.unwrap_or(false),
            };

        let response =
            self.client
                .get(format!("{}/rest/terms/contexts", &self.base_url))
                .header("Accept", "application/json")
                .header("Referer", "")
                .header("Content-Type", "application/json")
                .query(&query)
                .send()
                .await?;

        Ok(
            response
                .json()
                .await?
        )
    }

    pub async fn get_terms_similar_terms(
        &self,
        term: &str,
        retina_name: Option<&str>,
        context_id: Option<&str>,
        pos_type: Option<PosType>,
        get_fingerpint: Option<bool>,
        start_index: Option<u32>,
        max_results: Option<u32>,
    ) -> Result<GetTermsResponse, Box<dyn Error>> {
        let retina_name = retina_name.unwrap_or("en_general");

        let query =
            GetTermsSimilarTermsRequest {
                retina_name: retina_name.to_string(),
                term: term.to_string(),
                context_id: context_id.map(|c| c.to_string()),
                pos_type,
                start_index,
                max_results,
                get_fingerprint: get_fingerpint.unwrap_or(false),
            };

        let response =
            self.client
                .get(format!("{}/rest/terms/contexts", &self.base_url))
                .header("Accept", "application/json")
                .header("Referer", "")
                .header("Content-Type", "application/json")
                .query(&query)
                .send()
                .await?;

        Ok(
            response
                .json()
                .await?
        )
    }
}