-
-
Save makvoid/a76bcfcf516ac4f336e273f2dc7faa06 to your computer and use it in GitHub Desktop.
"How to use Algolia as a game engine debugging tool in Rust" Example #2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use serde::{Deserialize, Serialize, Serializer}; | |
use urlencoding; | |
// The credentials data | |
const ALGOLIA_AGENT: &str = "Algolia DataSender for Rust Dev (0.0.1)"; | |
// The reqwest client type used by the library | |
type ClientType = reqwest::blocking::Client; | |
pub struct AlgoliaSender { | |
app_id: String, | |
api_key: String, | |
index_name: String, | |
data_buffer: Vec<String>, | |
client: ClientType, | |
} | |
impl AlgoliaSender { | |
pub fn new(app_id: &str, api_key: &str, index_name: &str) -> Self { | |
AlgoliaSender { | |
app_id: String::from(app_id), | |
api_key: String::from(api_key), | |
index_name: String::from(index_name), | |
data_buffer: vec![], | |
client: ClientType::new(), | |
} | |
} | |
pub fn add_item<T>(&mut self, v: &T) | |
where | |
T: Serialize, | |
{ | |
match serde_json::to_string(v) { | |
Ok(serialized) => { | |
self.data_buffer.push(serialized); | |
} | |
Err(_) => {} | |
} | |
} | |
// Sends items to the ingestion endpoint in a batch job | |
pub fn send_items(&mut self) { | |
let index_name = self.index_name.clone(); | |
self.send_items_to_index(index_name.as_str()); | |
} | |
// Sends items to the ingestion endpoint in a batch job | |
pub fn send_items_to_index(&mut self, index_name: &str) { | |
// convert a pre-serialized JSON object into a request object for a batch request | |
fn build_batch_request_entry(data: &String) -> String { | |
format!("{{\"action\":\"updateObject\",\"body\":{}}}", data) | |
} | |
// wrap the individual requests into a batch | |
fn wrap_batch_request_entry(rows: &Vec<String>) -> String { | |
format!("{{\"requests\":[{}]}}", rows.join(",")) | |
} | |
// wrap the data | |
let data = wrap_batch_request_entry( | |
&self | |
.data_buffer | |
.iter() | |
.map(build_batch_request_entry) | |
.collect(), | |
); | |
// get the URI for the index | |
let uri = self.uri_for_index(index_name); | |
let uri_with_client = format!("{}?x-algolia-agent={}", uri, ALGOLIA_AGENT); | |
let res = self | |
.client | |
.post(uri_with_client) | |
.header("x-algolia-api-key", self.api_key.as_str()) | |
.header("x-algolia-application-id", self.app_id.as_str()) | |
.body(data) | |
.send(); | |
match res { | |
Err(_) => {} | |
Ok(resp) => { | |
let status = resp.status(); | |
let body = resp.text().unwrap_or_default(); | |
if status != 200 { | |
// log the problem for now | |
println!("ERROR while sending to Algolia: {}\n {}", status, body); | |
} | |
} | |
} | |
// TODO: this clean is tricky to place, as we want to keep unsent data, but it may accumulate to very large amounts | |
self.data_buffer.clear(); | |
} | |
// returns a full URI for an index name and the current app | |
fn uri_for_index(&self, index_name: &str) -> String { | |
// build the URI for the batch | |
let host = format!("{}.algolia.net", self.app_id.to_lowercase()); | |
let path = format!("/1/indexes/{}/batch", urlencoding::encode(index_name)); | |
format!("https://{}{}", host, path) | |
} | |
} | |
fn main() -> Result<(), Box<dyn std::error::Error>> { | |
#[derive(Serialize, Debug)] | |
struct Float3 { | |
#[serde(rename = "objectID")] | |
object_id: String, | |
x: f32, | |
y: f32, | |
z: f32, | |
} | |
// The credentials data | |
const APP_ID: &str = ""; | |
const INDEX_NAME: &str = ""; | |
const API_KEY: &str = ""; | |
const ALGOLIA_AGENT: &str = "Algolia DataSender for Rust Dev (0.0.1)"; | |
let mut sender = AlgoliaSender::new(APP_ID, API_KEY, INDEX_NAME); | |
sender.add_item(&Float3 { | |
object_id: String::from("point3"), | |
x: 0.1, | |
y: 0.2, | |
z: 0.3, | |
}); | |
sender.add_item(&Float3 { | |
object_id: String::from("point4"), | |
x: 1.1, | |
y: 1.2, | |
z: 1.3, | |
}); | |
sender.send_items(); | |
return Ok(()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment