use std::path::Path;
use crate::errors::OxenHttpError;
use crate::helpers::get_repo_async;
use crate::params::{app_data, parse_resource_async, path_param};
use crate::tasks;
use liboxen::repositories::data_frames::schemas;
use liboxen::repositories::revisions;
use liboxen::view::schema::SchemaWithPath;
use actix_web::{HttpRequest, HttpResponse};
use liboxen::error::OxenError;
use liboxen::view::entries::ResourceVersion;
use liboxen::view::{ListSchemaResponse, StatusMessage};
pub async fn list_or_get(req: HttpRequest) -> actix_web::Result<HttpResponse, OxenHttpError> {
let app_data = app_data(&req)?;
let namespace = path_param(&req, "namespace")?.to_string();
let repo_name = path_param(&req, "repo_name")?.to_string();
let repo = get_repo_async(app_data, &namespace, &repo_name).await?;
if let Ok(resource) = parse_resource_async(&req, &repo).await
&& resource.path != Path::new("")
{
let commit = resource.commit.clone().ok_or(OxenHttpError::NotFound)?;
log::debug!(
"schemas::list_or_get file {:?} commit {}",
resource.path,
commit
);
let schema = schemas::get_by_path_async(&repo, &commit, &resource.path).await?;
let mut schema_w_paths: Vec<SchemaWithPath> = vec![];
if let Some(schema) = schema {
schema_w_paths.push(SchemaWithPath::new(
resource.path.to_string_lossy().into(),
schema,
));
}
let resource = ResourceVersion {
path: resource.path.to_string_lossy().into(),
version: resource.version.to_string_lossy().into(),
};
let response = ListSchemaResponse {
status: StatusMessage::resource_found(),
schemas: schema_w_paths,
commit: Some(commit),
resource: Some(resource),
};
return Ok(HttpResponse::Ok().json(response));
}
let revision = path_param(&req, "resource")?.to_string();
let commit = revisions::get_async(&repo, &revision)
.await?
.ok_or_else(|| OxenError::RevisionNotFound(revision.as_str().into()))?;
log::debug!("schemas::list_or_get revision {revision} commit {commit}");
let listed = {
let commit = commit.clone();
tasks::spawn_blocking(move || schemas::list(&repo, &commit))
.await
.map_err(OxenError::from)??
};
let mut schema_w_paths: Vec<SchemaWithPath> = listed
.into_iter()
.map(|(path, schema)| SchemaWithPath::new(path.to_string_lossy().into(), schema))
.collect();
schema_w_paths.sort_by(|a, b| a.schema.hash.cmp(&b.schema.hash));
let response = ListSchemaResponse {
status: StatusMessage::resource_found(),
schemas: schema_w_paths,
commit: Some(commit),
resource: None,
};
Ok(HttpResponse::Ok().json(response))
}