use crate::{Result, stmt};
#[derive(Debug)]
pub struct ExecResponse {
pub values: Rows,
pub next_cursor: Option<stmt::Value>,
pub prev_cursor: Option<stmt::Value>,
}
#[derive(Debug)]
pub enum Rows {
Count(u64),
Value(stmt::Value),
Stream(stmt::ValueStream),
}
impl ExecResponse {
pub fn count(count: u64) -> Self {
Self {
values: Rows::Count(count),
next_cursor: None,
prev_cursor: None,
}
}
pub fn value_stream(values: impl Into<stmt::ValueStream>) -> Self {
Self {
values: Rows::value_stream(values),
next_cursor: None,
prev_cursor: None,
}
}
pub fn empty_value_stream() -> Self {
Self {
values: Rows::Stream(stmt::ValueStream::default()),
next_cursor: None,
prev_cursor: None,
}
}
pub fn from_rows(rows: Rows) -> Self {
Self {
values: rows,
next_cursor: None,
prev_cursor: None,
}
}
}
impl Rows {
pub fn value_stream(values: impl Into<stmt::ValueStream>) -> Self {
Self::Stream(values.into())
}
pub fn is_count(&self) -> bool {
matches!(self, Self::Count(_))
}
pub async fn buffer(&mut self) -> Result<()> {
if matches!(self, Rows::Stream(_)) {
let Rows::Stream(stream) = std::mem::replace(self, Rows::Count(0)) else {
unreachable!()
};
*self = Rows::Value(stmt::Value::List(stream.collect().await?));
}
Ok(())
}
pub async fn dup(&mut self) -> Result<Self> {
match self {
Rows::Count(count) => Ok(Rows::Count(*count)),
Rows::Value(value) => Ok(Rows::Value(value.clone())),
Rows::Stream(values) => Ok(Rows::Stream(values.dup().await?)),
}
}
pub fn try_clone(&self) -> Option<Self> {
match self {
Rows::Count(count) => Some(Rows::Count(*count)),
Rows::Value(value) => Some(Rows::Value(value.clone())),
Rows::Stream(values) => values.try_clone().map(Rows::Stream),
}
}
#[track_caller]
pub fn into_count(self) -> u64 {
match self {
Rows::Count(count) => count,
_ => todo!("rows={self:#?}"),
}
}
pub async fn collect_as_value(self) -> Result<stmt::Value> {
match self {
Rows::Count(_) => panic!("expected value; actual={self:#?}"),
Rows::Value(value) => Ok(value),
Rows::Stream(stream) => Ok(stmt::Value::List(stream.collect().await?)),
}
}
pub fn into_value_stream(self) -> stmt::ValueStream {
match self {
Rows::Value(stmt::Value::List(items)) => stmt::ValueStream::from_vec(items),
Rows::Stream(stream) => stream,
_ => panic!("expected ValueStream; actual={self:#?}"),
}
}
}