Skip to content

Commit

Permalink
Using less dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
Rahul committed Aug 10, 2023
1 parent b822d80 commit a851c0b
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 145 deletions.
40 changes: 4 additions & 36 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ rayon = "1.7.0"
git2 = "0.17.2"

# To query through buckets
regex = "1.9.3"
regex-lite = "0.1.0"
tokio = { version = "1.29.1", features = ["rt"] }

# For de/serialization
Expand Down
2 changes: 1 addition & 1 deletion src/commands/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub struct QueryCommand {

impl ExecuteCommand for QueryCommand {
fn exec(&self) -> Result<(), ScoopieError> {
let res = Buckets::query(QueryTerm::Regex(self.query.trim().into()))?;
let res = Buckets::query_fts(self.query.trim().into())?;
println!("{res}");
Ok(())
}
Expand Down
136 changes: 61 additions & 75 deletions src/core/buckets/query.rs
Original file line number Diff line number Diff line change
@@ -1,105 +1,91 @@
use std::collections::HashMap;
use std::fs::read_to_string;

use super::{Bucket, Buckets};
use super::{Bucket, Buckets, Manifest};

use crate::core::config::*;
use crate::error::*;

use rayon::prelude::*;
use regex::Regex;
use regex_lite::Regex;
use serde_json::from_str;

pub enum QueryTerm {
App(String),
Regex(String),
}

pub trait Query<T> {
pub trait Query<T>: Sized {
type Error;
fn query(query: T) -> Result<Self, Self::Error>
where
Self: Sized;
fn query_fts(query: T) -> Result<Self, Self::Error>;
fn query_app(query: T) -> Result<Self, Self::Error>;
}

impl Query<QueryTerm> for Buckets {
impl Query<&str> for Buckets {
type Error = ScoopieError;

fn query(q: QueryTerm) -> Result<Self, Self::Error> {
fn query_fts(query: &str) -> Result<Self, Self::Error> {
let buckets_dir = Config::buckets_dir()?;
let buckets = Config::read()?.known_buckets();

let query_func = match q {
QueryTerm::App(_) => <Bucket as QueryBucket<App>>::query,
QueryTerm::Regex(_) => <Bucket as QueryBucket<Rgx>>::query,
let query = match query.contains(" ") {
true => query
.split_whitespace()
.map(regex_lite::escape)
.collect::<Vec<_>>()
.join("|"),
false => query.into(),
};

let query = match q {
QueryTerm::App(s) => s,
QueryTerm::Regex(s) => match s.contains(" ") {
true => s
.split_whitespace()
.map(regex::escape)
.collect::<Vec<_>>()
.join("|"),
false => s,
},
let predicate = |(bucket_name, _): (String, _)| -> Option<(String, Bucket)> {
let content = read_to_string(buckets_dir.join(&bucket_name)).unwrap();
let bucket: Bucket = from_str(&content).unwrap();
let bucket: Bucket = bucket.query_fts(&query);

match !bucket.0.is_empty() {
true => Some((bucket_name, bucket)),
false => None,
}
};

let buckets: HashMap<_, _> = buckets
.into_par_iter()
.filter_map(|(name, _)| {
let content = read_to_string(buckets_dir.join(&name)).unwrap();
let bucket: Bucket = from_str(&content).unwrap();
let bucket = query_func(bucket, &query);

match !bucket.0.is_empty() {
true => Some((name, bucket)),
false => None,
}
})
.collect();

Ok(Buckets(buckets))
Ok(Buckets(
buckets.into_par_iter().filter_map(predicate).collect(),
))
}
}

struct App;
struct Rgx;
fn query_app(query: &str) -> Result<Self, Self::Error> {
let buckets_dir = Config::buckets_dir()?;
let buckets = Config::read()?.known_buckets();

trait QueryBucket<T> {
fn query(self, q: &str) -> Self
where
Self: Sized;
}
let predicate = |(bucket_name, _): (String, _)| -> Option<(String, Bucket)> {
let content = read_to_string(buckets_dir.join(&bucket_name)).unwrap();
let bucket: Bucket = from_str(&content).unwrap();
let bucket: Bucket = bucket.query_app(&query);

match !bucket.0.is_empty() {
true => Some((bucket_name, bucket)),
false => None,
}
};

impl QueryBucket<App> for Bucket {
fn query(self, q: &str) -> Self {
Bucket(
self.0
.into_par_iter()
.filter_map(|(app_name, manifest)| match app_name == q {
true => Some((app_name, manifest)),
false => None,
})
.collect(),
)
Ok(Buckets(
buckets.into_par_iter().filter_map(predicate).collect(),
))
}
}

impl QueryBucket<Rgx> for Bucket {
fn query(self, q: &str) -> Self {
let re = Regex::new(q).unwrap();
Bucket(
self.0
.iter()
.filter_map(|(app_name, manifest)| {
match re.is_match(&app_name) || re.is_match(&manifest.description) {
true => Some((app_name.clone(), manifest.clone())),
false => None,
}
})
.collect(),
)
trait QueryBucket<T>: Sized {
fn query_fts(self, q: &str) -> Self;
fn query_app(self, q: &str) -> Self;
}

impl QueryBucket<&str> for Bucket {
fn query_fts(self, q: &str) -> Self {
let predicate = |(app_name, manifest): &(String, Manifest)| -> bool {
let re = Regex::new(q).unwrap();
re.is_match(&app_name) || re.is_match(&manifest.description)
};

Bucket(self.0.into_par_iter().filter(predicate).collect())
}

fn query_app(self, q: &str) -> Self {
let predicate = |(app_name, _): &(String, _)| -> bool { app_name == q };

Bucket(self.0.into_par_iter().filter(predicate).collect())
}
}
40 changes: 8 additions & 32 deletions src/core/download/downloader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,21 +108,19 @@ impl Builder<&str> for Downloader {

let item = match query.split_once('/') {
Some((bucket, app)) => {
let manifest = Buckets::query(QueryTerm::App(app.into()))?
.get_app_from(app, bucket)
.ok_or(ScoopieError::Download(DownloadError::NoAppFoundInBucket(
let manifest = Buckets::query_app(app)?.get_app_from(app, bucket).ok_or(
ScoopieError::Download(DownloadError::NoAppFoundInBucket(
app.into(),
bucket.into(),
)))?;
)),
)?;

DownloadEntry::new(app.into(), manifest)
}
None => {
let manifest = Buckets::query(QueryTerm::App(app_name.into()))?
.get_app(app_name)
.ok_or(ScoopieError::Download(DownloadError::NoAppFound(
app_name.into(),
)))?;
let manifest = Buckets::query_app(app_name)?.get_app(app_name).ok_or(
ScoopieError::Download(DownloadError::NoAppFound(app_name.into())),
)?;

DownloadEntry::new(app_name.into(), manifest)
}
Expand Down Expand Up @@ -189,29 +187,7 @@ fn get_package_size(url: &Url) -> u64 {
let client = reqwest::blocking::Client::new();

// Create a HEAD request using reqwest
let response = client.head(url.clone()).send().unwrap();

// Get the content disposition header
if let Some(content_disposition) = response.headers().get(reqwest::header::CONTENT_DISPOSITION)
{
if let Some(filename) = content_disposition.to_str().ok().and_then(|header| {
let param = "filename=";
let start = header.find(param)? + param.len();
let end = header[start..].find(';').unwrap_or(header[start..].len());
Some(header[start..start + end].to_owned())
}) {
println!("Suggested Filename: {}", filename);
} else {
println!("Filename not found in Content-Disposition header");
}
} else {
println!("Content-Disposition header not found");
}

let response = reqwest::blocking::Client::new()
.head(url.clone())
.send()
.unwrap();
let response = client.get(url.clone()).send().unwrap();

response.content_length().unwrap_or_default()
}

0 comments on commit a851c0b

Please sign in to comment.