1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT license.
*/
use crate::{Any, Checker};
pub trait Input {
/// Return the discriminant associated with this type.
///
/// This is used to map inputs types to their respective parsers.
///
/// Well formed implementations should always return the same result.
fn tag() -> &'static str;
/// Attempt to deserialize an opaque object from the raw `serialized` representation.
///
/// Deserialized values can be constructed and returned via [`Checker::any`],
/// [`Any::new`] or [`Any::raw`].
///
/// If using the [`Any`] constructors directly, implementations should associate
/// [`Self::tag`] with the returned `Any`. If [`Checker::any`] is used - this will
/// happen automatically.
///
/// Implementations are **strongly** encouraged to implement
/// [`CheckDeserialization`](crate::CheckDeserialization) and use this API to ensure
/// shared resources (like input files or output files) are correctly resolved and
/// properly shared among all jobs in a benchmark run.
fn try_deserialize(
serialized: &serde_json::Value,
checker: &mut Checker,
) -> anyhow::Result<Any>;
/// Print an example JSON representation of objects this input is expected to parse.
///
/// Well-formed implementations should ensure that passing the returned
/// [`serde_json::Value`] back to [`Self::try_deserialize`] correctly deserializes,
/// though it need not necessarily pass
/// [`CheckDeserialization`](crate::CheckDeserialization).
fn example() -> anyhow::Result<serde_json::Value>;
}
/// A registered input. See [`crate::registry::Inputs::get`].
#[derive(Clone, Copy)]
pub struct Registered<'a>(pub(crate) &'a dyn DynInput);
impl Registered<'_> {
/// Return the input tag of the registered input.
///
/// See: [`Input::tag`].
pub fn tag(&self) -> &'static str {
self.0.tag()
}
/// Try to deserialize raw JSON into the dynamic type of the input.
///
/// See: [`Input::try_deserialize`].
pub fn try_deserialize(
&self,
serialized: &serde_json::Value,
checker: &mut Checker,
) -> anyhow::Result<Any> {
self.0.try_deserialize(serialized, checker)
}
/// Return an example JSON for the dynamic type of the input.
///
/// See: [`Input::example`].
pub fn example(&self) -> anyhow::Result<serde_json::Value> {
self.0.example()
}
}
impl std::fmt::Debug for Registered<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("input::Registered")
.field("tag", &self.tag())
.finish()
}
}
//////////////
// Internal //
//////////////
#[derive(Debug)]
pub(crate) struct Wrapper<T>(std::marker::PhantomData<T>);
impl<T> Wrapper<T> {
pub(crate) const INSTANCE: Self = Self::new();
pub(crate) const fn new() -> Self {
Self(std::marker::PhantomData)
}
}
impl<T> Clone for Wrapper<T> {
fn clone(&self) -> Self {
*self
}
}
impl<T> Copy for Wrapper<T> {}
pub(crate) trait DynInput {
fn tag(&self) -> &'static str;
fn try_deserialize(
&self,
serialized: &serde_json::Value,
checker: &mut Checker,
) -> anyhow::Result<Any>;
fn example(&self) -> anyhow::Result<serde_json::Value>;
}
impl<T> DynInput for Wrapper<T>
where
T: Input,
{
fn tag(&self) -> &'static str {
T::tag()
}
fn try_deserialize(
&self,
serialized: &serde_json::Value,
checker: &mut Checker,
) -> anyhow::Result<Any> {
T::try_deserialize(serialized, checker)
}
fn example(&self) -> anyhow::Result<serde_json::Value> {
T::example()
}
}