pub struct Score<L> { /* private fields */ }Expand description
A question with an answer on a scale of levels.
The levels go from the lowest to the highest, and each one has a value of the type L. The API
knows a level only by its text. The answer is a ScoreAnswer, with the probability of each
level, and it gives the values back. score! makes a Score that the compiler
checks. The constructors make one from data. A Score has 1 to 10 levels, and each level is
different.
§Examples
The smallest Score has a list of levels, from the lowest to the highest. The answer gives a level back:
use system2::Score;
let urgency = Score::new(
"How urgent is the ticket?",
["It can wait.", "It needs an answer today.", "It needs an answer now."],
)?;A level can be a value of the caller. A closure gives its text, and the answer gives the value back:
struct Deadline {
level: String,
hours: u32,
}
let deadlines = vec![
Deadline { level: "It can wait.".to_string(), hours: 72 },
Deadline { level: "It needs an answer now.".to_string(), hours: 1 },
];
let urgency = Score::with_values("How urgent is the ticket?", &deadlines, |deadline| {
&deadline.level
})?;An enum that derives Levels gives its variants as the levels:
use system2::Levels;
#[derive(Debug, Clone, Copy, PartialEq, Levels)]
enum Urgency {
Low,
Medium,
High,
}
let instructions = "How urgent is the ticket?".to_string();
let urgency = Score::<Urgency>::of(instructions)?;score! takes the same forms, and the compiler checks them. A question with
no variable can be a constant:
use system2::prelude::*;
use system2::Score;
#[derive(Debug, Clone, Copy, PartialEq, Levels)]
enum Urgency {
Low,
Medium,
High,
}
const URGENCY: Score<Urgency> = score!("How urgent is the ticket?", Urgency);
const SIZE: Score<&str> = score!("How big is the fix?", ["A line.", "A file.", "A module."]);
const DAYS: Score<u32> = score!("How long does the fix take?", [("A day.", 1), ("A week.", 5)]);
let urgency = URGENCY.ask("The site is down.").await?;
if *urgency.most_likely() == Urgency::High || urgency.score() > 1.5 { /* … */ }Implementations§
Source§impl<L> Score<L>
impl<L> Score<L>
Sourcepub fn new(
instructions: impl Serialize,
levels: impl IntoIterator<Item = L>,
) -> Result<Self, InvalidScore>where
L: Serialize,
pub fn new(
instructions: impl Serialize,
levels: impl IntoIterator<Item = L>,
) -> Result<Self, InvalidScore>where
L: Serialize,
Makes a Score from levels that come from data, from the lowest to the highest.
Each level is any Serialize value, and it follows the rules of the instructions. The
answer gives the level back.
§Errors
InvalidScore::Instructionsif the instructions do not serialize, are empty, or are a bare number orbool.InvalidScore::Levelif a level breaks a rule of the instructions.InvalidScore::Countif there are no levels, or more than 10.InvalidScore::Duplicateif two levels are the same.
Sourcepub fn with_values<D: Serialize>(
instructions: impl Serialize,
values: impl IntoIterator<Item = L>,
level: impl FnMut(&L) -> D,
) -> Result<Self, InvalidScore>
pub fn with_values<D: Serialize>( instructions: impl Serialize, values: impl IntoIterator<Item = L>, level: impl FnMut(&L) -> D, ) -> Result<Self, InvalidScore>
Makes a Score from the values of the caller, with a closure that gives their levels.
The values go from the lowest level to the highest. Each level is any Serialize value, and
it follows the rules of the instructions. The values need no Clone, and the answer gives
a value back.
§Errors
InvalidScore::Instructionsif the instructions do not serialize, are empty, or are a bare number orbool.InvalidScore::Levelif a level breaks a rule of the instructions.InvalidScore::Countif there are no values, or more than 10.InvalidScore::Duplicateif two levels are the same.
Sourcepub fn of(instructions: impl Serialize) -> Result<Self, InvalidScore>where
L: Levels,
pub fn of(instructions: impl Serialize) -> Result<Self, InvalidScore>where
L: Levels,
Makes a Score from instructions that come from data, with the levels of the type L.
It validates the levels of L again, as Score::with_values does.
§Errors
InvalidScore::Instructions if the instructions do not serialize, are empty, or are a
bare number or bool. The derive of Levels validates the levels, so another variant
does not occur.
Sourcepub const fn tag<T>(self, tag: T) -> Tagged<Self, T>
pub const fn tag<T>(self, tag: T) -> Tagged<Self, T>
Puts a tag next to the question, so that the answer comes back next to it.
It is the same as Ask::tag, but it is a const fn, so a constant can
hold a tagged question.
Sourcepub fn answer(
self,
score: f64,
confidence: f64,
probabilities: impl IntoIterator<Item = f64>,
) -> Result<ScoreAnswer<L>, InvalidAnswer>
pub fn answer( self, score: f64, confidence: f64, probabilities: impl IntoIterator<Item = f64>, ) -> Result<ScoreAnswer<L>, InvalidAnswer>
Builds the answer that a response with these values would give.
score is the mean level, from 0 to the index of the last level, confidence is the
confidence of the API, and probabilities has one probability for each level, lowest
first. It’s for tests of your own decision code, and it goes through the same checks as a
response from the API.
§Errors
Returns InvalidAnswer if the score is not from 0 to the index of the last level, if
there is not one probability for each level, or if another value is not from 0 to 1.