aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Eilertsen <haraldei@anduin.net>2023-03-29 13:08:09 +0200
committerHarald Eilertsen <haraldei@anduin.net>2023-03-29 13:08:09 +0200
commit8100cff32bf0c87dc19fba78f3faac8090f863da (patch)
tree7c6315dbb83162b8d91aae53b920c2e7f20a4268
parenta4b9520f430ce188ba9165dcabd3320763ff2e16 (diff)
downloadrust-zotapi-8100cff32bf0c87dc19fba78f3faac8090f863da.tar.gz
rust-zotapi-8100cff32bf0c87dc19fba78f3faac8090f863da.tar.bz2
rust-zotapi-8100cff32bf0c87dc19fba78f3faac8090f863da.zip
Another reqrite...
Third time must be where it sits I hope. I felt the API was getting a bit too distracted by unnecessary constructs and abstractions, so I'm trying to simplify it by making it more straight forward. The idea now is to have one main API class (ZotApi), and all the various remote API's as public methods on this basic class. Iow, the ZotApi class is mainly based on the existing `Client` class, which is then being phased out. And instead of having each API tied to the data type they return, I'm just adding methods that will return the respective data types. This should reduce coupling between the returned data, and the API calls themselves.
-rw-r--r--Cargo.toml2
-rw-r--r--src/bin/zot/main.rs39
-rw-r--r--src/bin/zot/zot/abconfig.rs38
-rw-r--r--src/bin/zot/zot/channel_stream.rs113
-rw-r--r--src/bin/zot/zot/group.rs70
-rw-r--r--src/bin/zot/zot/item.rs57
-rw-r--r--src/bin/zot/zot/mod.rs5
-rw-r--r--src/bin/zot/zot/network_stream.rs104
-rw-r--r--src/error.rs7
-rw-r--r--src/lib.rs31
-rw-r--r--src/verify.rs23
-rw-r--r--src/xchan.rs54
-rw-r--r--src/zotapi.rs57
13 files changed, 98 insertions, 502 deletions
diff --git a/Cargo.toml b/Cargo.toml
index a7c789f..a271637 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -29,7 +29,7 @@ serde_json = "1.0"
serde_qs = "0.8"
tokio = { version = "1.27", features = ["full"] }
url = "2.2"
-zotapi-derive = { version = "0.1.0", path = "zotapi-derive" }
+#zotapi-derive = { version = "0.1.0", path = "zotapi-derive" }
[dev-dependencies]
base64 = "0.13"
diff --git a/src/bin/zot/main.rs b/src/bin/zot/main.rs
index bf7b9b8..d09b5d4 100644
--- a/src/bin/zot/main.rs
+++ b/src/bin/zot/main.rs
@@ -18,45 +18,40 @@
use clap::{clap_app, crate_authors, crate_version};
use dotenv::dotenv;
use std::env;
-use std::str::FromStr;
-use zotapi::ZotAPI;
-
-mod zot;
#[tokio::main]
-async fn main() {
+async fn main() -> Result<(), Box<(dyn std::error::Error + 'static)>> {
dotenv().ok();
let site = env::var("HZ_SITE").expect("SITE variable expected");
- let user = env::var("HZ_USER").expect("USER variable expected");
+ let channel = env::var("HZ_CHANNEL").expect("CHANNEL variable expected");
let password = env::var("HZ_PASSWORD").expect("PASSWORD variable expected");
let matches = clap_app!(app =>
(name: "zot")
(version: crate_version!())
(author: crate_authors!())
- (about: "zotapi command line client")
+ (about: "zotapi command line client.")
+ (@arg raw: --raw "Display raw json payload.")
+ (@arg site: --site "Site to connect to.")
+ (@arg channel: --channel "The channel to connect as.")
+ (@arg password: --password "The password.")
(@subcommand verify =>
(about: "Verify")
- (@arg raw: --raw "Display raw json payload")
)
(@subcommand channel =>
(about: "Fetch the channel stream")
- (@arg raw: --raw "Display raw json payload")
)
(@subcommand network =>
(about: "Fetch the network stream")
- (@arg raw: --raw "Display raw json payload")
)
(@subcommand abook =>
(about: "Fetch address book/contact info")
- (@arg raw: --raw "Display raw json payload")
)
(@subcommand abconfig =>
(about: "Fetch abconfig")
)
(@subcommand group =>
(about: "Fetch privacy groups")
- (@arg raw: --raw "Display raw json payload")
(@group selector =>
(@arg ID: --id +takes_value "Fetch members of group <ID>")
(@arg GNAME: --name +takes_value "Fetch members of group <GNAME>")
@@ -64,7 +59,6 @@ async fn main() {
)
(@subcommand xchan =>
(about: "Fetch xchan info")
- (@arg raw: --raw "Display raw json payload")
(@arg addr: --addr "ID is given as webbie (default)")
(@arg hash: --hash "ID is given as xchan hash")
(@arg guid: --guid "ID is given as a GUID")
@@ -89,17 +83,14 @@ async fn main() {
)
.get_matches();
- let client = zotapi::client(&site, &user, &password);
+ let z = zotapi::new(&site, &channel, &password);
- match matches.subcommand() {
- ("verify", Some(m)) => {
- let r = zotapi::Channel::z();
- if m.is_present("raw") {
- println!("{}", r.fetch_raw(&client).await.unwrap());
- } else {
- println!("{:?}", r.fetch(&client).await);
- }
+ Ok(match matches.subcommand() {
+ ("verify", Some(_)) => {
+ let channel = z.verify().await;
+ println!("{:?}", channel);
}
+ /*
("channel", Some(m)) => {
let raw = m.is_present("raw");
zot::channel_stream::fetch(&client, raw).await;
@@ -178,8 +169,10 @@ async fn main() {
("post", Some(m)) => {
zot::item::post(&client, m).await;
}
+ */
_ => {
+ println!("Not a known command, or it's not implemented yet.");
println!("{}", matches.usage());
}
- }
+ })
}
diff --git a/src/bin/zot/zot/abconfig.rs b/src/bin/zot/zot/abconfig.rs
deleted file mode 100644
index 1d67a54..0000000
--- a/src/bin/zot/zot/abconfig.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Example Zot API command line utility, part of zotapi.
- * Copyright (C) 2018 Harald Eilertsen <haraldei@anduin.net>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-use zotapi::{self, ZotAPI};
-
-pub async fn fetch(client: &zotapi::Client) {
- match zotapi::ABConfig::z().fetch(&client).await {
- Ok(v) => {
- println!("Id: Chan: Cat: Key: Val: xchan:");
- for entry in v {
- println!("{:6} {:6} {:15} {:15} {:4} {}",
- entry.id,
- entry.chan,
- entry.cat,
- entry.k,
- entry.v,
- entry.xchan);
- }
- }
- Err(e) => {
- println!("{:?}", e);
- }
- }
-}
diff --git a/src/bin/zot/zot/channel_stream.rs b/src/bin/zot/zot/channel_stream.rs
deleted file mode 100644
index 68a5402..0000000
--- a/src/bin/zot/zot/channel_stream.rs
+++ /dev/null
@@ -1,113 +0,0 @@
-/* Example Zot API command line utility, part of zotapi.
- * Copyright (C) 2018 Harald Eilertsen <haraldei@anduin.net>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-use zotapi;
-
-use serde_json;
-use std::iter::Iterator;
-
-pub async fn fetch(client: &zotapi::Client, raw: bool) {
- match zotapi::channel_stream().fetch(&client).await {
- Ok(payload) => {
- if raw {
- println!("{}", payload);
- } else {
- list(&payload);
- }
- }
- Err(e) => {
- println!("Error getting channel stream: {:?}", e);
- }
- }
-}
-
-fn list(payload: &str) {
- match serde_json::from_str(&payload) {
- Ok(serde_json::Value::Array(v)) => {
- for item in v.into_iter() {
- print_item(&item);
- }
- }
- Ok(_) => println!("Wrong type returned, expected an array."),
- Err(e) => {
- println!("Error: {}", e);
- }
- }
-}
-
-fn get_str(v: &serde_json::Value) -> &str {
- v.as_str().unwrap_or("")
-}
-
-fn get_verb(item: &serde_json::Value) -> &str {
- match get_str(&item["verb"]).split("/").last() {
- Some("post") => "posted",
- Some("like") => "liked",
- Some("share") => "shared",
- Some("dislike") => "disliked",
- _ => "unknown verb",
- }
-}
-
-fn get_object_type(item: &serde_json::Value) -> &str {
- get_str(&item["object_type"])
- .split("/")
- .last()
- .unwrap_or("unknown object")
-}
-
-fn get_tags(item: &serde_json::Value) -> String {
- match item["tags"] {
- serde_json::Value::Array(ref v) => v
- .iter()
- .map(|t| {
- let prefix = match get_str(&t["type"]) {
- "hashtag" => "#",
- "forum" => "!",
- "mention" => "@",
- _ => "",
- };
- format!("{}{}", prefix, get_str(&t["tag"]))
- })
- .collect::<Vec<_>>()
- .join(", "),
- serde_json::Value::Null => String::new(),
- _ => String::from("invalid tags, expected array..."),
- }
-}
-
-fn print_item(item: &serde_json::Value) {
- let author = &item["author"];
-
- println!("{} {} {} a {}:",
- get_str(&item["created"]),
- get_str(&author["name"]),
- get_verb(&item),
- get_object_type(&item));
-
- let title = get_str(&item["title"]);
- if title.len() > 0 {
- println!("Title: {}", get_str(&item["title"]));
- }
-
- let tags = get_tags(&item);
- if tags.len() > 0 {
- println!("Tags : {}", get_tags(&item));
- }
-
- println!("\n{}\n", get_str(&item["body"]));
-}
diff --git a/src/bin/zot/zot/group.rs b/src/bin/zot/zot/group.rs
deleted file mode 100644
index 9264cdc..0000000
--- a/src/bin/zot/zot/group.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Example Zot API command line utility, part of zotapi.
- * Copyright (C) 2018 Harald Eilertsen <haraldei@anduin.net>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-use serde_json::{from_str, Value};
-
-pub fn list(data: &str) {
- if let Ok(Value::Array(groups)) = from_str(&data) {
- println!("Id | Group name | uid | flags | hash");
- println!("----+------------------+-----+-------+-------------------------");
-
- for group in groups {
- let mut flags = String::new();
-
- if let Some(visible) = group["visible"].as_u64() {
- if visible != 0 {
- flags += "v";
- }
- }
-
- if let Some(deleted) = group["deleted"].as_u64() {
- if deleted != 0 {
- flags += "d";
- }
- }
-
- print!(
- "{:>3} | {:16} | {:>3} | {:5} | {}\n",
- group["id"].as_u64().unwrap(),
- group["gname"].as_str().unwrap(),
- group["uid"].as_u64().unwrap(),
- flags,
- group["hash"].as_str().unwrap()
- );
- }
- } else {
- eprintln!("Invalid data");
- }
-}
-
-pub fn list_members(data: &str) {
- if let Ok(Value::Array(members)) = from_str(&data) {
- println!("Id | Name | Address");
- println!("----+-------------------------------+------------------------");
-
- for member in members {
- println!(
- "{:>3} | {:29} | {}",
- member["id"].as_u64().unwrap(),
- member["xchan_name"].as_str().unwrap(),
- member["xchan_addr"].as_str().unwrap()
- );
- }
- } else {
- eprintln!("Invalid data");
- }
-}
diff --git a/src/bin/zot/zot/item.rs b/src/bin/zot/zot/item.rs
deleted file mode 100644
index dbb39ba..0000000
--- a/src/bin/zot/zot/item.rs
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Example Zot API command line utility, part of zotapi.
- * Copyright (C) 2018 Harald Eilertsen <haraldei@anduin.net>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-use clap::ArgMatches;
-use zotapi;
-
-pub async fn post(client: &zotapi::Client, args: &ArgMatches<'_>) {
- let mut msg = zotapi::item();
- let body: String;
-
- if let Some(file) = dbg!(args.value_of("FILE")) {
- let buf = std::fs::read(file).expect("Invalid file name");
- body = String::from_utf8(buf).expect("File contained invalid char data.");
- msg.body(&body);
- }
-
- if let Some(title) = dbg!(args.value_of("TITLE")) {
- msg.title(title);
- }
-
- if let Some(file) = dbg!(args.value_of("ATTACH")) {
- msg.file(file);
- }
-
- if let Some(groups) = dbg!(args.value_of("GROUP")) {
- for g in groups.split(",") {
- msg.group_allow(g);
- }
- }
-
- match msg.create(&client).await {
- Ok(res) => {
- if res.success {
- println!("New item with id {} posted successfully!", res.item_id);
- } else {
- println!("The item could not be posted.");
- }
- }
- Err(e) => {
- println!("Error posting message: {:?}", e);
- }
- }
-}
diff --git a/src/bin/zot/zot/mod.rs b/src/bin/zot/zot/mod.rs
deleted file mode 100644
index 23e25ec..0000000
--- a/src/bin/zot/zot/mod.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-pub mod abconfig;
-pub mod channel_stream;
-pub mod group;
-pub mod item;
-pub mod network_stream;
diff --git a/src/bin/zot/zot/network_stream.rs b/src/bin/zot/zot/network_stream.rs
deleted file mode 100644
index a5a7142..0000000
--- a/src/bin/zot/zot/network_stream.rs
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Example Zot API command line utility, part of zotapi.
- * Copyright (C) 2018 Harald Eilertsen <haraldei@anduin.net>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-use zotapi;
-
-use serde_json;
-use std::iter::Iterator;
-
-pub async fn fetch(client: &zotapi::Client, raw: bool) {
- match zotapi::network_stream().fetch(&client).await {
- Ok(payload) => {
- if raw {
- println!("{}", payload);
- } else {
- list(&payload);
- }
- }
- Err(e) => {
- println!("Error getting channel stream: {:?}", e);
- }
- }
-}
-
-fn list(payload: &str) {
- match serde_json::from_str(&payload) {
- Ok(serde_json::Value::Array(v)) => {
- for item in v.into_iter() {
- print_item(&item);
- println!("-----");
- }
- }
- Ok(_) => println!("Wrong type returned, expected an array."),
- Err(e) => {
- println!("Error: {}", e);
- }
- }
-}
-
-fn get_str(v: &serde_json::Value) -> &str {
- v.as_str().unwrap_or("")
-}
-
-fn get_verb(item: &serde_json::Value) -> &str {
- match get_str(&item["verb"]).split("/").last() {
- Some("post") => "posted",
- Some("like") => "liked",
- Some("share") => "shared",
- Some("dislike") => "disliked",
- _ => "unknown verb",
- }
-}
-
-fn get_object_type(item: &serde_json::Value) -> &str {
- get_str(&item["object_type"])
- .split("/")
- .last()
- .unwrap_or("unknown object")
-}
-
-fn get_tags(item: &serde_json::Value) -> String {
- match item["tags"] {
- serde_json::Value::Array(ref v) => v
- .iter()
- .map(|t| {
- let prefix = match get_str(&t["type"]) {
- "hashtag" => "#",
- "forum" => "!",
- "mention" => "@",
- _ => "",
- };
- format!("{}{}", prefix, get_str(&t["tag"]))
- })
- .collect::<Vec<_>>()
- .join(", "),
- serde_json::Value::Null => String::new(),
- _ => String::from("invalid tags, expected array..."),
- }
-}
-
-fn print_item(item: &serde_json::Value) {
- let author = &item["author"];
- print!("{} ", get_str(&item["created"]));
- print!("{} ", get_str(&author["name"]));
- println!("{} a {}", get_verb(&item), get_object_type(&item));
- println!("URL: {}", get_str(&author["url"]));
- println!("Proto: {}", get_str(&author["network"]));
- println!("Title: {}", get_str(&item["title"]));
- println!("Tags : {}", get_tags(&item));
- println!("Message:\n{}", get_str(&item["body"]));
-}
diff --git a/src/error.rs b/src/error.rs
index 34fea2d..2954bea 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -23,6 +23,7 @@ pub enum Error {
Http(reqwest::Error),
Io(std::io::Error),
Json(serde_json::Error),
+ ParseError(url::ParseError),
Qs(serde_qs::Error),
Unauthorized,
Unknown,
@@ -46,6 +47,12 @@ impl From<serde_json::Error> for Error {
}
}
+impl From<url::ParseError> for Error {
+ fn from(e: url::ParseError) -> Error {
+ Error::ParseError(e)
+ }
+}
+
impl From<serde_qs::Error> for Error {
fn from(e: serde_qs::Error) -> Error {
Error::Qs(e)
diff --git a/src/lib.rs b/src/lib.rs
index 086ecfb..df661f7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,29 +14,30 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
-mod abconfig;
-mod abook;
-mod channel_stream;
-mod client;
+// mod abconfig;
+// mod abook;
+// mod channel_stream;
+// mod client;
mod error;
-mod group;
-mod item;
-mod network_stream;
+// mod group;
+// mod item;
+// mod network_stream;
mod verify;
mod xchan;
mod zotapi;
-pub use abconfig::ABConfig;
-pub use abook::Abook;
-pub use channel_stream::channel_stream;
-pub use client::*;
+// pub use abconfig::ABConfig;
+// pub use abook::Abook;
+// pub use channel_stream::channel_stream;
+// pub use client::*;
pub use error::Error;
-pub use group::{group, group_members};
-pub use item::item;
-pub use network_stream::network_stream;
+// pub use group::{group, group_members};
+// pub use item::item;
+// pub use network_stream::network_stream;
pub use verify::Channel;
pub use xchan::XChan;
-pub use zotapi::ZotAPI;
+// pub use zotapi::ZotAPI;
+pub use zotapi::new;
#[cfg(test)]
mod tests {
diff --git a/src/verify.rs b/src/verify.rs
index 57e250d..bab1f18 100644
--- a/src/verify.rs
+++ b/src/verify.rs
@@ -14,12 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
-use crate::{client::Client, error::Error, XChan, ZotAPI};
+use crate::{error::Error, XChan};
use serde::Deserialize;
use std::convert::TryFrom;
-use zotapi_derive::ZotAPI;
+//use zotapi_derive::ZotAPI;
-#[derive(Deserialize, Debug, ZotAPI)]
+#[derive(Deserialize, Debug)]
pub struct Channel {
#[serde(alias = "channel_id")]
pub id: u32,
@@ -137,20 +137,3 @@ impl<'a> TryFrom<&'a str> for Channel {
Ok(serde_json::from_str(s)?)
}
}
-
-#[derive(Default)]
-pub struct ChannelRequest;
-
-impl ChannelRequest {
- pub async fn fetch_raw(&self, client: &Client) -> Result<String, Error> {
- Ok(client.get("verify").send().await?.text().await?)
- }
-
- pub async fn fetch(&self, client: &Client) -> Result<Channel, Error> {
- let raw = self.fetch_raw(&client).await?;
- let mut channel: Channel = serde_json::from_str(&raw)?;
- channel.xchan = serde_json::from_str(&raw)?;
-
- Ok(channel)
- }
-}
diff --git a/src/xchan.rs b/src/xchan.rs
index 4544f08..e4f6893 100644
--- a/src/xchan.rs
+++ b/src/xchan.rs
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
-use crate::{client::Client, error::Error};
+use crate::{error::Error};
use serde::Deserialize;
use std::convert::TryFrom;
@@ -103,12 +103,6 @@ pub struct XChan {
pub deleted: u32,
}
-impl XChan {
- pub fn z<'a>() -> XChanRequest<'a> {
- XChanRequest::default()
- }
-}
-
impl<'a> TryFrom<&'a str> for XChan {
type Error = Error;
@@ -116,49 +110,3 @@ impl<'a> TryFrom<&'a str> for XChan {
Ok(serde_json::from_str(s)?)
}
}
-
-enum XChanRequestSelector<'a> {
- Address(&'a str),
- Hash(&'a str),
- GUID(&'a str),
-}
-
-#[derive(Default)]
-pub struct XChanRequest<'a> {
- data: Option<XChanRequestSelector<'a>>,
-}
-
-impl<'a> XChanRequest<'a> {
- pub fn by_address(&mut self, addr: &'a str) -> &mut XChanRequest<'a> {
- self.data = Some(XChanRequestSelector::Address(addr));
- self
- }
-
- pub fn by_hash(&mut self, hash: &'a str) -> &mut XChanRequest<'a> {
- self.data = Some(XChanRequestSelector::Hash(hash));
- self
- }
-
- pub fn by_guid(&mut self, guid: &'a str) -> &mut XChanRequest<'a> {
- self.data = Some(XChanRequestSelector::GUID(guid));
- self
- }
-
- pub async fn fetch_raw(&self, client: &Client) -> Result<String, Error> {
- let mut req = client.get("xchan");
-
- if let Some(sel) = &self.data {
- req = match sel {
- XChanRequestSelector::Address(s) => req.query(&[("address", s.to_string())]),
- XChanRequestSelector::Hash(s) => req.query(&[("hash", s.to_string())]),
- XChanRequestSelector::GUID(s) => req.query(&[("guid", s.to_string())]),
- };
- }
-
- Ok(req.send().await?.text().await?)
- }
-
- pub async fn fetch(&self, client: &Client) -> Result<XChan, Error> {
- Ok(XChan::try_from(self.fetch_raw(&client).await?.as_str())?)
- }
-}
diff --git a/src/zotapi.rs b/src/zotapi.rs
index 87a2f0e..9e13d99 100644
--- a/src/zotapi.rs
+++ b/src/zotapi.rs
@@ -14,8 +14,59 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
-pub trait ZotAPI<T: Default> {
- fn z() -> T {
- T::default()
+use crate::Channel;
+use url::Url;
+use reqwest::{
+ self,
+ header::{ACCEPT},
+};
+use serde::Serialize;
+
+#[derive(Debug)]
+pub struct ZotApi {
+ client: reqwest::Client,
+ base_url: Url,
+ channel: String,
+ pw: String,
+}
+
+pub fn new(url: &str, channel: &str, pw: &str) -> ZotApi {
+ ZotApi {
+ client: reqwest::Client::new(),
+ base_url: Url::parse(url).unwrap().join("api/z/1.0/").unwrap(),
+ channel: String::from(channel),
+ pw: String::from(pw),
+ }
+}
+
+impl ZotApi {
+ pub async fn verify(&self) -> Result<Channel, Box<dyn std::error::Error>> {
+ let raw = self.get("verify").send().await?.text().await?;
+ let mut channel: Channel = serde_json::from_str(&raw)?;
+ channel.xchan = serde_json::from_str(&raw)?;
+
+ Ok(channel)
+ }
+
+
+ /// Return a RequestBuilder object that's set up with the correct
+ /// path and headers for performing a zot api request.
+ pub fn get(&self, path: &str) -> reqwest::RequestBuilder {
+ self.client.get(&self.url(path, &()))
+ .header(ACCEPT, "application/json")
+ .basic_auth(self.channel.clone(), Some(self.pw.clone()))
+ }
+
+ fn url<T>(&self, path: &str, args: &T) -> String
+ where
+ T: Serialize + std::fmt::Debug,
+ {
+ let mut r = self.base_url.clone().join(path).unwrap();
+
+ if let Ok(a) = serde_qs::to_string(dbg!(args)) {
+ r.set_query(Some(&a));
+ }
+
+ r.to_string()
}
}