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 { first.unwrap_or(DEFAULT_FIRST).clamp(0, MAX_FIRST) } pub(crate) fn parse_oid(hex: &str) -> Result { 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) -> Result { let Some(c) = c else { return Ok(0) }; c.parse::() .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, 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, 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 { 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, }))) }