feat: impl dashboard & issue list

This commit is contained in:
2026-05-06 01:42:38 +08:00
parent bef3a0b9ed
commit 7de0039d38
36 changed files with 2381 additions and 107 deletions

47
src/api/mock.rs Normal file
View File

@@ -0,0 +1,47 @@
use serde::de::DeserializeOwned;
use crate::api::{self, issues, repo, user};
include!(concat!(env!("OUT_DIR"), "/github_fixtures.rs"));
pub(super) fn is_enabled() -> bool {
std::env::var("NOVEM_GITHUB_FIXTURES")
.ok()
.map(|value| {
!matches!(
value.trim().to_ascii_lowercase().as_str(),
"" | "0" | "false" | "off"
)
})
.unwrap_or(false)
}
pub(crate) fn fetch_user() -> Result<user::User, api::Error> {
parse_fixture("user.fetch", user_fetch())
}
pub(crate) fn list_repos() -> Result<Vec<repo::Repository>, api::Error> {
parse_fixture("repo.list", repo_list())
}
pub(crate) fn list_pull_requests(
filter: Option<&str>,
page: u32,
) -> Result<Vec<issues::Issue>, api::Error> {
let filter = filter.unwrap_or_default();
let json = issues_pull_requests(filter, page).ok_or_else(|| {
api::Error::MissingMockFixture(format!("issues.pull_requests filter={filter} page={page}"))
})?;
parse_fixture(&format!("issues.pull_requests.{filter}.page{page}"), json)
}
fn parse_fixture<T>(name: &str, json: &'static str) -> Result<T, api::Error>
where
T: DeserializeOwned,
{
serde_json::from_str(json).map_err(|err| {
println!("[mock fixture] failed to parse {name}: {err}");
api::Error::MalformedResponse(err)
})
}