diff --git a/crates/turborepo-api-client/src/spaces.rs b/crates/turborepo-api-client/src/spaces.rs index 6a78205bc35b1..2c34573b371ab 100644 --- a/crates/turborepo-api-client/src/spaces.rs +++ b/crates/turborepo-api-client/src/spaces.rs @@ -1,9 +1,9 @@ -use std::collections::HashSet; +use std::{backtrace::Backtrace, collections::HashSet, str::FromStr}; use async_graphql::{Enum, SimpleObject}; use chrono::{DateTime, Local}; use reqwest::Method; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use turbopath::AnchoredSystemPath; use turborepo_vercel_api::SpaceRun; @@ -48,6 +48,21 @@ pub enum CacheStatus { Miss, } +impl FromStr for CacheStatus { + type Err = Error; + + fn from_str(s: &str) -> Result { + match s { + "HIT" => Ok(Self::Hit), + "MISS" => Ok(Self::Miss), + _ => Err(Error::UnknownCachingStatus( + s.to_string(), + Backtrace::capture(), + )), + } + } +} + #[derive(Debug, Serialize, Copy, Clone, PartialEq, Eq, Enum)] #[serde(rename_all = "UPPERCASE")] pub enum CacheSource { @@ -55,7 +70,7 @@ pub enum CacheSource { Remote, } -#[derive(Debug, Serialize, SimpleObject, PartialEq, Eq, Hash)] +#[derive(Debug, Deserialize, Serialize, SimpleObject, PartialEq, Eq, Hash)] pub struct TaskId { pub package: String, pub task: String, diff --git a/crates/turborepo-db/src/lib.rs b/crates/turborepo-db/src/lib.rs index 07bb4f172912f..4fb124a4d91b1 100644 --- a/crates/turborepo-db/src/lib.rs +++ b/crates/turborepo-db/src/lib.rs @@ -99,22 +99,42 @@ impl DatabaseHandle { ) .bind(run_id.to_string()); Ok(query - .map(|row: SqliteRow| SpaceTaskSummary { - key: row.get("key"), - name: row.get("name"), - workspace: row.get("workspace"), - hash: row.get("hash"), - start_time: row.get("start_time"), - end_time: row.get("end_time"), - cache: SpacesCacheStatus { - status: row.get("cache_status"), - source: None, - time_saved: row.get("time_saved"), - }, - exit_code: row.get("exit_code"), - dependencies: row.get("dependencies"), - dependents: row.get("dependents"), - logs: row.get("logs"), + .try_map(|row: SqliteRow| { + let dependencies: Option = row.get("dependencies"); + let dependents: Option = row.get("dependents"); + let cache_status: String = row.get("cache_status"); + + let dependencies = dependencies + .as_deref() + .map(serde_json::from_str) + .transpose() + .map_err(|err| sqlx::Error::Decode(Box::new(err)))?; + + let dependents = dependents + .as_deref() + .map(serde_json::from_str) + .transpose() + .map_err(|err| sqlx::Error::Decode(Box::new(err)))?; + + Ok(SpaceTaskSummary { + key: row.get("key"), + name: row.get("name"), + workspace: row.get("workspace"), + hash: row.get("hash"), + start_time: row.get("start_time"), + end_time: row.get("end_time"), + cache: SpacesCacheStatus { + status: cache_status + .parse() + .map_err(|err| sqlx::Error::Decode(Box::new(err)))?, + source: None, + time_saved: row.get("time_saved"), + }, + exit_code: row.get("exit_code"), + dependencies, + dependents, + logs: row.get("logs"), + }) }) .fetch_all(&self.pool) .await?)