Skip to content
Clone
5ba9d7d
104 lines 3.0 KB Rust
use std::sync::Arc;
use gitbaby::tags::types::TagType as GbTagType;
use crate::context::facade::GitContext;
use crate::graphql::error::{map_git_baby, to_gql};
use crate::graphql::types::{BlobObj, CommitObj, GitObject, TagObj, TagShape, TreeObj};
use crate::service::GitService;
use crate::share::errors::GitError;
pub const DEFAULT_FIRST: i32 = 30;
pub const MAX_FIRST: i32 = 100;
pub(crate) fn clamp_first(first: Option<i32>) -> i32 {
first.unwrap_or(DEFAULT_FIRST).clamp(0, MAX_FIRST)
}
pub(crate) fn parse_oid(hex: &str) -> Result<gix::hash::ObjectId, async_graphql::Error> {
gix::hash::ObjectId::from_hex(hex.as_bytes())
.map_err(|e| async_graphql::Error::new(format!("invalid object id `{hex}`: {e}")))
}
pub(crate) fn parse_cursor(c: Option<String>) -> Result<usize, async_graphql::Error> {
let Some(c) = c else { return Ok(0) };
c.parse::<usize>()
.map_err(|e| async_graphql::Error::new(format!("invalid cursor `{c}`: {e}")))
}
pub fn map_git(e: GitError) -> async_graphql::Error {
to_gql(e)
}
#[derive(Clone)]
pub struct RepoCtx {
pub svc: Arc<GitService>,
pub ctx: GitContext,
pub space_name: String,
pub repo_name: String,
pub baby: gitbaby::GitBaby,
}
impl RepoCtx {
pub async fn parents_of(
&self,
oid: &gix::hash::ObjectId,
) -> Result<Vec<gix::hash::ObjectId>, async_graphql::Error> {
let info = self
.baby
.get_commit(&oid.to_string())
.await
.map_err(map_git_baby)?;
Ok(info.parents)
}
}
pub(crate) const EMPTY_SHA1: [u8; 20] = [0; 20];
pub(crate) fn parse_oid_or_default(s: &str) -> gix::hash::ObjectId {
gix::hash::ObjectId::from_hex(s.as_bytes())
.unwrap_or_else(|_| gix::hash::ObjectId::from_bytes_or_panic(&EMPTY_SHA1))
}
pub async fn resolve_git_object(
repo: &RepoCtx,
oid: gix::hash::ObjectId,
) -> async_graphql::Result<GitObject> {
let baby = &repo.baby;
if let Ok(info) = baby
.get_commit(&oid.to_string())
.await
.map_err(map_git_baby)
{
return Ok(GitObject::Commit(CommitObj::from_info(&info)));
}
if let Ok(entries) = baby
.get_tree_entries(&oid.to_string(), std::path::Path::new(""))
.await
.map_err(map_git_baby)
{
return Ok(GitObject::Tree(TreeObj {
oid: crate::graphql::scalars::ObjectIdScalar(oid),
entry_count: entries.len() as i32,
}));
}
if let Ok(blob) = baby
.get_blob(oid, gitbaby::blob::types::GetBlobOptions { limit: None })
.await
.map_err(map_git_baby)
{
return Ok(GitObject::Blob(BlobObj::new(
blob.info.oid,
&blob.data,
blob.info.size,
)));
}
Ok(GitObject::Tag(TagObj::from(TagShape {
name: format!("tag:{}", oid.to_string().get(..7).unwrap_or("")),
id: oid,
target: oid,
tag_type: GbTagType::Annotated.into(),
message: None,
tagger: None,
})))
}