use jammi_db::catalog::channel_repo::{ChannelColumn, ChannelColumnType, ChannelSpec};
use jammi_db::ChannelId;
use tonic::Status;
use crate::proto::catalog as pb;
pub fn parse_channel_id(id: &str) -> Result<ChannelId, Status> {
if id.is_empty() {
return Err(Status::invalid_argument("channel_id is required"));
}
ChannelId::new(id).map_err(|e| Status::invalid_argument(e.to_string()))
}
pub fn channel_to_proto(spec: &ChannelSpec) -> pb::Channel {
pb::Channel {
channel_id: spec.id.as_str().to_string(),
priority: spec.priority,
columns: columns_to_proto(&spec.columns),
}
}
pub fn channel_from_proto(channel: pb::Channel) -> Result<ChannelSpec, Status> {
Ok(ChannelSpec {
id: parse_channel_id(&channel.channel_id)?,
priority: channel.priority,
columns: columns_from_proto(channel.columns)?,
})
}
pub fn columns_from_proto(columns: Vec<pb::ChannelColumn>) -> Result<Vec<ChannelColumn>, Status> {
columns
.into_iter()
.map(|c| {
if c.name.is_empty() {
return Err(Status::invalid_argument("column name is required"));
}
Ok(ChannelColumn {
name: c.name,
data_type: column_type_from_proto(c.data_type)?,
})
})
.collect()
}
pub fn columns_to_proto(columns: &[ChannelColumn]) -> Vec<pb::ChannelColumn> {
columns
.iter()
.map(|c| pb::ChannelColumn {
name: c.name.clone(),
data_type: column_type_to_proto(c.data_type) as i32,
})
.collect()
}
fn column_type_to_proto(ty: ChannelColumnType) -> pb::ChannelColumnType {
match ty {
ChannelColumnType::Float32 => pb::ChannelColumnType::Float32,
ChannelColumnType::Float64 => pb::ChannelColumnType::Float64,
ChannelColumnType::Int32 => pb::ChannelColumnType::Int32,
ChannelColumnType::Int64 => pb::ChannelColumnType::Int64,
ChannelColumnType::Utf8 => pb::ChannelColumnType::Utf8,
ChannelColumnType::Boolean => pb::ChannelColumnType::Boolean,
}
}
fn column_type_from_proto(ty: i32) -> Result<ChannelColumnType, Status> {
match pb::ChannelColumnType::try_from(ty) {
Ok(pb::ChannelColumnType::Float32) => Ok(ChannelColumnType::Float32),
Ok(pb::ChannelColumnType::Float64) => Ok(ChannelColumnType::Float64),
Ok(pb::ChannelColumnType::Int32) => Ok(ChannelColumnType::Int32),
Ok(pb::ChannelColumnType::Int64) => Ok(ChannelColumnType::Int64),
Ok(pb::ChannelColumnType::Utf8) => Ok(ChannelColumnType::Utf8),
Ok(pb::ChannelColumnType::Boolean) => Ok(ChannelColumnType::Boolean),
Ok(pb::ChannelColumnType::Unspecified) | Err(_) => Err(Status::invalid_argument(
"column data_type must be specified",
)),
}
}