You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
4.9 KiB
Rust
192 lines
4.9 KiB
Rust
use std::sync::Arc;
|
|
|
|
use crate::serialization::Operation;
|
|
|
|
#[derive(Copy, Clone, Debug)]
|
|
pub struct OutputIdx(pub u32);
|
|
|
|
#[derive(Copy, Clone, Debug)]
|
|
pub struct OwnOutputIdx(pub u32);
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct OperationOutput<'a> {
|
|
kind: OperationOutputKind<'a>,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
enum OperationOutputKind<'a> {
|
|
Owned(Arc<dyn Operation + 'a>, OutputIdx),
|
|
Borrowed(&'a dyn Operation, OutputIdx),
|
|
}
|
|
|
|
impl<'a> OperationOutput<'a> {
|
|
pub(crate) fn owned(op: Arc<dyn Operation + 'a>, idx: OutputIdx) -> Self {
|
|
Self {
|
|
kind: OperationOutputKind::Owned(op, idx),
|
|
}
|
|
}
|
|
|
|
pub(crate) fn borrowed(op: &'a dyn Operation, idx: OutputIdx) -> Self {
|
|
Self {
|
|
kind: OperationOutputKind::Borrowed(op, idx),
|
|
}
|
|
}
|
|
|
|
pub(crate) fn operation(&self) -> &dyn Operation {
|
|
match self.kind {
|
|
OperationOutputKind::Owned(ref op, ..) => op.as_ref(),
|
|
OperationOutputKind::Borrowed(ref op, ..) => *op,
|
|
}
|
|
}
|
|
|
|
pub(crate) fn output(&self) -> OutputIdx {
|
|
match self.kind {
|
|
OperationOutputKind::Owned(_, output) | OperationOutputKind::Borrowed(_, output) => {
|
|
output
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Into<i64> for OutputIdx {
|
|
fn into(self) -> i64 {
|
|
self.0.into()
|
|
}
|
|
}
|
|
impl Into<i64> for &OutputIdx {
|
|
fn into(self) -> i64 {
|
|
self.0.into()
|
|
}
|
|
}
|
|
|
|
impl Into<i64> for OwnOutputIdx {
|
|
fn into(self) -> i64 {
|
|
self.0.into()
|
|
}
|
|
}
|
|
impl Into<i64> for &OwnOutputIdx {
|
|
fn into(self) -> i64 {
|
|
self.0.into()
|
|
}
|
|
}
|
|
|
|
impl Into<i32> for OutputIdx {
|
|
fn into(self) -> i32 {
|
|
self.0 as i32
|
|
}
|
|
}
|
|
impl Into<i32> for &OutputIdx {
|
|
fn into(self) -> i32 {
|
|
self.0 as i32
|
|
}
|
|
}
|
|
|
|
impl Into<i32> for OwnOutputIdx {
|
|
fn into(self) -> i32 {
|
|
self.0 as i32
|
|
}
|
|
}
|
|
impl Into<i32> for &OwnOutputIdx {
|
|
fn into(self) -> i32 {
|
|
self.0 as i32
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
pub mod test {
|
|
#[macro_export]
|
|
macro_rules! check_op {
|
|
($op:expr, $(|$name:ident| $value:expr,)*) => ($crate::check_op!($op, $(|$name| $value),*));
|
|
($op:expr, $(|$name:ident| $value:expr),*) => {{
|
|
#[allow(unused_imports)]
|
|
use crate::serialization::{Context, Operation};
|
|
|
|
let mut context = Context::default();
|
|
let serialized = $op.serialize(&mut context).unwrap();
|
|
|
|
$(crate::check_op_property!(serialized, context, $name, $value));*
|
|
}};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! check_op_property {
|
|
($serialized:expr, $context:expr, op, $value:expr) => {{
|
|
use std::io::Cursor;
|
|
|
|
use buildkit_proto::pb;
|
|
use prost::Message;
|
|
|
|
assert_eq!(
|
|
pb::Op::decode(Cursor::new(&$serialized.bytes)).unwrap().op,
|
|
Some($value)
|
|
);
|
|
}};
|
|
|
|
($serialized:expr, $context:expr, inputs, $value:expr) => {{
|
|
use std::io::Cursor;
|
|
|
|
use buildkit_proto::pb;
|
|
use prost::Message;
|
|
|
|
assert_eq!(
|
|
pb::Op::decode(Cursor::new(&$serialized.bytes))
|
|
.unwrap()
|
|
.inputs
|
|
.into_iter()
|
|
.map(|input| (input.digest, input.index))
|
|
.collect::<Vec<_>>(),
|
|
$value
|
|
.into_iter()
|
|
.map(|input: (&str, i64)| (String::from(input.0), input.1))
|
|
.collect::<Vec<_>>()
|
|
);
|
|
}};
|
|
|
|
($serialized:expr, $context:expr, cached_tail, $value:expr) => {
|
|
assert_eq!(
|
|
$context
|
|
.registered_nodes_iter()
|
|
.map(|node| node.digest.clone())
|
|
.collect::<Vec<_>>(),
|
|
crate::utils::test::to_vec($value),
|
|
);
|
|
};
|
|
|
|
($serialized:expr, $context:expr, caps, $value:expr) => {{
|
|
let mut caps = $serialized
|
|
.metadata
|
|
.caps
|
|
.into_iter()
|
|
.map(|pair| pair.0)
|
|
.collect::<Vec<_>>();
|
|
|
|
caps.sort();
|
|
assert_eq!(caps, crate::utils::test::to_vec($value));
|
|
}};
|
|
|
|
($serialized:expr, $context:expr, description, $value:expr) => {
|
|
assert_eq!(
|
|
$serialized.metadata.description,
|
|
crate::utils::test::to_map($value),
|
|
);
|
|
};
|
|
|
|
($serialized:expr, $context:expr, digest, $value:expr) => {
|
|
assert_eq!($serialized.digest, $value);
|
|
};
|
|
}
|
|
|
|
use std::collections::HashMap;
|
|
|
|
pub fn to_map(pairs: Vec<(&str, &str)>) -> HashMap<String, String> {
|
|
pairs
|
|
.into_iter()
|
|
.map(|(key, value): (&str, &str)| (key.into(), value.into()))
|
|
.collect()
|
|
}
|
|
|
|
pub fn to_vec(items: Vec<&str>) -> Vec<String> {
|
|
items.into_iter().map(String::from).collect()
|
|
}
|
|
}
|