/
basuev
/
gverse
Обзор
Документация
Войти
/
basuev
/
gverse
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/api/trees.rs
121 строка
3 KB
basuev
initial commit: gverse v0.1.0
27 май 2026, 08:52
27 май 2026, 08:52
98b24dd
Код
Авторство
О чём код?
use crate::api::split_repo; use crate::client::Client; use crate::config::Config; use crate::error::{Error, Result}; use crate::output::{Format, print_value}; use clap::Subcommand; use reqwest::Method; use serde_json::{Map, Value}; use std::path::PathBuf; use tokio::fs; #[derive(Subcommand, Debug)] pub enum TreesCmd { Get { repo: String, sha: String, #[arg(long)] recursive: bool, #[arg(long)] page: Option<u32>, #[arg(long)] limit: Option<u32>, }, Create { repo: String, #[arg(long, conflicts_with = "tree_inline")] tree_file: Option<PathBuf>, #[arg(long = "tree", conflicts_with = "tree_file", value_name = "JSON")] tree_inline: Option<String>, #[arg(long)] base_tree: Option<String>, }, } pub async fn run(cmd: TreesCmd, cfg: &Config, profile: Option<&str>, fmt: Format) -> Result<()> { let p = cfg.active_profile(profile)?; let client = Client::new(p)?; match cmd { TreesCmd::Get { repo, sha, recursive, page, limit, } => get(&client, &repo, &sha, recursive, page, limit, fmt).await, TreesCmd::Create { repo, tree_file, tree_inline, base_tree, } => create(&client, &repo, tree_file, tree_inline, base_tree, fmt).await, } } async fn get( client: &Client, repo: &str, sha: &str, recursive: bool, page: Option<u32>, limit: Option<u32>, fmt: Format, ) -> Result<()> { let (owner, name) = split_repo(repo)?; let mut q: Vec<(&str, String)> = Vec::new(); if recursive { q.push(("recursive", "true".to_string())); } if let Some(p) = page { q.push(("page", p.to_string())); } if let Some(l) = limit { q.push(("limit", l.to_string())); } let v = client .get_value(&format!("/repos/{owner}/{name}/git/trees/{sha}"), &q) .await?; print_value(fmt, &v); Ok(()) } async fn create( client: &Client, repo: &str, tree_file: Option<PathBuf>, tree_inline: Option<String>, base_tree: Option<String>, fmt: Format, ) -> Result<()> { let (owner, name) = split_repo(repo)?; let tree_json: Value = match (tree_file, tree_inline) { (Some(p), None) => { let s = fs::read_to_string(&p).await?; serde_json::from_str(&s)? } (None, Some(s)) => serde_json::from_str(&s)?, (None, None) => { return Err(Error::Invalid("must provide --tree-file or --tree".into())); } (Some(_), Some(_)) => unreachable!(), }; if !tree_json.is_array() { return Err(Error::Invalid( "tree payload must be a JSON array of entries".into(), )); } let mut body = Map::new(); body.insert("tree".into(), tree_json); if let Some(b) = base_tree { body.insert("base_tree".into(), Value::String(b)); } let v = client .send_json( Method::POST, &format!("/repos/{owner}/{name}/git/trees"), &Value::Object(body), ) .await?; print_value(fmt, &v); Ok(()) }