From 791cb38a41a260679d3acb5d4b423d7f4314f826 Mon Sep 17 00:00:00 2001 From: Valentin Brandl Date: Sat, 4 May 2019 15:45:25 +0200 Subject: [PATCH] Implement generator and use custom result type --- src/main.rs | 51 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/src/main.rs b/src/main.rs index 49c20f4..aad2c5d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,8 +13,8 @@ mod service; use crate::{ cache::CacheState, - error::Error, - service::{Bitbucket, GitHub, Gitlab, Service}, + error::{Error, Result}, + service::{Bitbucket, FormService, GitHub, Gitlab, Service}, }; use actix_web::{ error::ErrorBadRequest, @@ -27,6 +27,7 @@ use futures::{unsync::mpsc, Stream}; use git2::Repository; use number_prefix::{NumberPrefix, Prefixed, Standalone}; use std::{ + borrow::Cow, fs::create_dir_all, path::{Path, PathBuf}, process::Command, @@ -42,6 +43,13 @@ pub struct VersionInfo<'a> { pub version: &'a str, } +#[derive(Deserialize, Serialize)] +struct GeneratorForm<'a> { + service: FormService, + user: Cow<'a, str>, + repo: Cow<'a, str>, +} + const VERSION_INFO: VersionInfo = VersionInfo { commit: env!("VERGEN_SHA_SHORT"), version: env!("CARGO_PKG_VERSION"), @@ -106,14 +114,14 @@ struct Opt { workers: usize, } -fn pull(path: impl AsRef) -> Result<(), Error> { +fn pull(path: impl AsRef) -> Result<()> { let repo = Repository::open_bare(path)?; let mut origin = repo.find_remote("origin")?; origin.fetch(&["refs/heads/*:refs/heads/*"], None, None)?; Ok(()) } -fn hoc(repo: &str, repo_dir: &str, cache_dir: &str) -> Result<(u64, String), Error> { +fn hoc(repo: &str, repo_dir: &str, cache_dir: &str) -> Result<(u64, String)> { let repo_dir = format!("{}/{}", repo_dir, repo); let cache_dir = format!("{}/{}.json", cache_dir, repo); let cache_dir = Path::new(&cache_dir); @@ -164,7 +172,7 @@ fn hoc(repo: &str, repo_dir: &str, cache_dir: &str) -> Result<(u64, String), Err s.split_whitespace() .take(2) .map(str::parse::) - .filter_map(Result::ok) + .filter_map(std::result::Result::ok) .sum::() }) .sum(); @@ -175,7 +183,7 @@ fn hoc(repo: &str, repo_dir: &str, cache_dir: &str) -> Result<(u64, String), Err Ok((cache.count, head)) } -fn remote_exists(url: &str) -> Result { +fn remote_exists(url: &str) -> Result { Ok(CLIENT.head(url).send()?.status() == reqwest::StatusCode::OK) } @@ -195,10 +203,10 @@ fn handle_hoc_request( state: web::Data>, data: web::Path<(String, String)>, mapper: F, -) -> Result +) -> Result where T: Service, - F: Fn(HocResult) -> Result, + F: Fn(HocResult) -> Result, { hoc_request::(state, data).and_then(mapper) } @@ -206,7 +214,7 @@ where fn hoc_request( state: web::Data>, data: web::Path<(String, String)>, -) -> Result { +) -> Result { let repo = format!("{}/{}", data.0.to_lowercase(), data.1.to_lowercase()); let service_path = format!("{}/{}", T::domain(), repo); let path = format!("{}/{}", state.repos, service_path); @@ -242,7 +250,7 @@ fn hoc_request( fn calculate_hoc( state: web::Data>, data: web::Path<(String, String)>, -) -> Result { +) -> Result { let mapper = |r| match r { HocResult::NotFound => Ok(p404()), HocResult::Hoc { hoc_pretty, .. } => { @@ -275,7 +283,7 @@ fn calculate_hoc( fn overview( state: web::Data>, data: web::Path<(String, String)>, -) -> Result { +) -> Result { let mapper = |r| match r { HocResult::NotFound => Ok(p404()), HocResult::Hoc { @@ -317,6 +325,26 @@ fn index() -> HttpResponse { .body(INDEX.as_slice()) } +#[post("/generate")] +fn generate(params: web::Form) -> Result { + let repo = format!("{}/{}", params.user, params.repo); + let mut buf = Vec::new(); + templates::generate( + &mut buf, + VERSION_INFO, + &OPT.domain, + params.service.url(), + params.service.service(), + &repo, + )?; + let (tx, rx_body) = mpsc::unbounded(); + let _ = tx.unbounded_send(Bytes::from(buf)); + + Ok(HttpResponse::Ok() + .content_type("text/html") + .streaming(rx_body.map_err(|_| ErrorBadRequest("bad request")))) +} + fn p404() -> HttpResponse { HttpResponse::NotFound() .content_type("text/html") @@ -343,6 +371,7 @@ fn main() -> std::io::Result<()> { .wrap(middleware::Logger::default()) .service(index) .service(css) + .service(generate) .service(web::resource("/github/{user}/{repo}").to(calculate_hoc::)) .service(web::resource("/gitlab/{user}/{repo}").to(calculate_hoc::)) .service(web::resource("/bitbucket/{user}/{repo}").to(calculate_hoc::))