Commit ac88a386 authored by Akshay S Dinesh's avatar Akshay S Dinesh

feat: insert and update addons

parent d3af5985
This diff is collapsed.
[package]
name = "addon-distributor"
name = "addon_distributor"
version = "0.1.0"
authors = ["Akshay S Dinesh <asdofindia@gmail.com>"]
edition = "2018"
......@@ -7,5 +7,6 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
dialoguer = "0.4.0"
serde = { version = "1.0.101", features = ["derive"] }
serde_json = "1.0.41"
use serde::Serialize;
//! # Addon Distributor
//!
//! `addon_distributor` is a simple, fast tool to create, update, and manage json files that serve
//! as update file for firefox extensions
use std::error::Error;
use std::fs::File;
use std::io::{BufReader, BufWriter};
use std::path::Path;
use std::collections::BTreeMap;
use dialoguer::{theme::ColorfulTheme, Select};
use serde::{Serialize, Deserialize};
use serde_json;
#[derive(Serialize)]
#[derive(Serialize, Deserialize, Debug)]
struct Gecko {
#[serde(skip_serializing_if = "Option::is_none")]
strict_min_version: Option<String>,
......@@ -11,13 +23,13 @@ struct Gecko {
advisory_max_version: Option<String>
}
#[derive(Serialize)]
#[derive(Serialize, Deserialize, Debug)]
struct Application {
gecko: Gecko
}
#[derive(Serialize)]
struct Update {
#[derive(Serialize, Deserialize, Debug)]
pub struct Update {
version: String,
#[serde(skip_serializing_if = "Option::is_none")]
update_link: Option<String>,
......@@ -31,33 +43,59 @@ struct Update {
applications: Option<Application>
}
#[derive(Serialize)]
struct Addon {
#[derive(Serialize, Deserialize, Debug)]
pub struct Addon {
#[serde(skip_serializing_if = "Option::is_none")]
updates: Option<Vec<Update>>
}
mod distributor {
#[derive(Serialize, Deserialize, Debug)]
pub struct Addons {
addons: BTreeMap<String, Addon>
}
pub mod distributor {
use super::*;
pub fn addon_struct() -> serde_json::Value {
let update = Update {
version: String::from("1.0"),
update_link: None,
update_hash: None,
update_info_url: None,
multiprocess_compatible: None,
applications: None
pub fn get_addon_names(addons: Addons) -> Vec<String> {
return addons.addons.keys().cloned().collect();
}
pub fn upsert_addon(addons: &mut Addons, name: String, addon: Addon) {
addons.addons.insert(name, addon);
}
pub fn insert_update_in_addon(mut addon: Addon, update: Update) {
match addon.updates {
None => addon.updates = Some(vec![update]),
Some(mut vector) => vector.insert(0, update)
};
let addon = Addon { updates: Some(vec![update])};
serde_json::json!({
"addons": {
"some-addon": addon
}
})
}
pub fn empty_json() -> serde_json::Value {
serde_json::json!({})
pub fn read_updates_from_file<P: AsRef<Path>>(path: P) -> Result<Addons,Box<dyn Error>> {
let file = File::open(path)?;
let reader = BufReader::new(file);
let updates: Addons = serde_json::from_reader(reader)?;
Ok(updates)
}
pub fn write_updates_to_file<P: AsRef<Path>>(path: P, updates: &Addons) -> Result<(), Box<dyn Error>> {
let file = File::create(path)?;
let writer = BufWriter::new(file);
let result = serde_json::to_writer_pretty(writer, &updates)?;
Ok(result)
}
pub fn addon_chooser(selections: Vec<String>) -> Option<usize> {
let selection = Select::with_theme(&ColorfulTheme::default())
.with_prompt("Choose your addon")
.items(&selections[..])
.interact_opt()
.unwrap();
return selection;
}
}
......@@ -65,15 +103,37 @@ mod distributor {
mod tests {
use super::*;
const TEST_FILE : &str = "tests/test.json";
#[test]
fn read_updates_from_file() {
let filename = TEST_FILE;
distributor::read_updates_from_file(filename).expect("Unable to open file");
}
#[test]
fn read_and_write() {
let readfile = TEST_FILE;
let writefile = TEST_FILE;
let read = distributor::read_updates_from_file(readfile).unwrap();
let write = distributor::write_updates_to_file(writefile, &read).unwrap();
assert_eq!(write, ())
}
#[test]
fn empty_json() {
assert_eq!(distributor::empty_json().to_string(), String::from("{}"));
fn get_addon_names() {
let addons = distributor::read_updates_from_file(TEST_FILE).unwrap();
let addon_names = distributor::get_addon_names(addons);
assert_eq!(addon_names, ["{abcd1234-1abc-1234-12ab-abcdef123456}"]);
}
#[test]
fn addon_struct() {
assert_eq!(
distributor::addon_struct().to_string(),
String::from(r#"{"addons":{"some-addon":{"updates":[{"version":"1.0"}]}}}"#));
fn upsert_addon() {
let mut addons = distributor::read_updates_from_file(TEST_FILE).unwrap();
let new_addon = Addon {
updates: None
};
distributor::upsert_addon(&mut addons, String::from("testing"), new_addon);
}
}
fn main() {
println!("Hello, world!");
}
{
"addons": {
"{abcd1234-1abc-1234-12ab-abcdef123456}": {
"updates": [
{
"version": "0.1",
"update_link": "https://example.com/addon-0.1.xpi"
},
{
"version": "0.2",
"update_link": "http://example.com/addon-0.2.xpi",
"update_hash": "sha256:fe93c2156f05f20621df1723b0f39c8ab28cdbeec342efa95535d3abff932096"
},
{
"version": "0.3",
"update_link": "https://example.com/addon-0.3.xpi",
"applications": {
"gecko": {
"strict_min_version": "44"
}
}
}
]
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment