wip: pr file diffing
This commit is contained in:
126
src/api/repo.rs
126
src/api/repo.rs
@@ -1,6 +1,13 @@
|
||||
use futures::{FutureExt, TryFutureExt};
|
||||
use reqwest::Method;
|
||||
use serde::Deserialize;
|
||||
use tokio::sync::OwnedRwLockReadGuard;
|
||||
|
||||
use crate::{api, query};
|
||||
use crate::{
|
||||
api,
|
||||
query::{self, Query, fetch_query},
|
||||
util::file,
|
||||
};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Repository {
|
||||
@@ -22,6 +29,13 @@ pub struct Owner {
|
||||
pub html_url: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FileRef {
|
||||
pub repo_slug: String,
|
||||
pub path: String,
|
||||
pub reff: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct List;
|
||||
|
||||
@@ -50,3 +64,113 @@ impl query::QueryFn for List {
|
||||
api::parse_response(res).await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FetchFileContent {
|
||||
pub repo_slug: String,
|
||||
pub path: String,
|
||||
pub reff: Option<String>,
|
||||
}
|
||||
|
||||
impl query::QueryFn for FetchFileContent {
|
||||
type Data = bytes::Bytes;
|
||||
type Error = api::Error;
|
||||
type Context = api::QueryContext;
|
||||
|
||||
fn key(&self) -> query::Key {
|
||||
match &self.reff {
|
||||
| Some(reff) => format!("repo/fetch/{}/{}/{}", self.repo_slug, self.path, reff).into(),
|
||||
| None => format!("repo/fetch/{}/{}", self.repo_slug, self.path).into(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn run(&self, c: &Self::Context) -> Result<Self::Data, Self::Error> {
|
||||
#[cfg(debug_assertions)]
|
||||
if c.should_use_fixtures {
|
||||
return super::mock::fetch_file_content(
|
||||
&self.repo_slug,
|
||||
&self.path,
|
||||
self.reff.as_deref(),
|
||||
);
|
||||
}
|
||||
|
||||
let path = match &self.reff {
|
||||
| Some(reff) => format!(
|
||||
"/repos/{}/contents/{}?ref={}",
|
||||
self.repo_slug, self.path, reff
|
||||
),
|
||||
| None => format!("/repos/{}/contents/{}", self.repo_slug, self.path),
|
||||
};
|
||||
|
||||
let res = c
|
||||
.github_request(Method::GET, &path)?
|
||||
.header("Accept", "application/vnd.github.raw+json")
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
api::raw_content(res).await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct QueryFileDiff {
|
||||
pub base: FileRef,
|
||||
pub head: FileRef,
|
||||
}
|
||||
|
||||
impl query::QueryFn for QueryFileDiff {
|
||||
type Data = Option<()>;
|
||||
type Error = api::Error;
|
||||
type Context = api::QueryContext;
|
||||
|
||||
fn key(&self) -> query::Key {
|
||||
format!(
|
||||
"repo/diff/{}/{}/{}",
|
||||
self.base.repo_slug, self.base.path, self.head.path
|
||||
)
|
||||
.into()
|
||||
}
|
||||
|
||||
async fn run(&self, c: &Self::Context) -> Result<Self::Data, Self::Error> {
|
||||
async fn fetch_content(
|
||||
r: &FileRef,
|
||||
c: &<QueryFileDiff as query::QueryFn>::Context,
|
||||
) -> Result<Option<bytes::Bytes>, api::Error> {
|
||||
let path = match &r.reff {
|
||||
| Some(reff) => format!("/repos/{}/contents/{}?ref={}", r.repo_slug, r.path, reff),
|
||||
| None => format!("/repos/{}/contents/{}", r.repo_slug, r.path),
|
||||
};
|
||||
|
||||
let res = c
|
||||
.github_request(Method::GET, &path)?
|
||||
.header("Accept", "application/vnd.github.raw+json")
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
res.headers().get("Content-Type");
|
||||
|
||||
let bytes = api::raw_content(res).await?;
|
||||
let file::ContentType::Text = file::classify_content(&bytes) else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
Ok(Some(bytes))
|
||||
}
|
||||
|
||||
let (old, new) = tokio::join!(fetch_content(&self.base, c), fetch_content(&self.head, c),);
|
||||
|
||||
match (old, new) {
|
||||
| (Ok(Some(ref old)), Ok(Some(ref new))) => {
|
||||
let diff = similar::TextDiff::from_lines::<[u8]>(old, new);
|
||||
for change in diff.iter_all_changes() {}
|
||||
}
|
||||
| _ => {
|
||||
return Err(api::Error::MalformedResponse(
|
||||
"failed to fetch content".to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user