Skip to main content

Score

Struct Score 

Source
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>

Source

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
Source

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
Source

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.

Source

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.

Source

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.

Trait Implementations§

Source§

impl<L: Clone> Clone for Score<L>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<L: Debug> Debug for Score<L>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<L> QuestionSet for Score<L>

Source§

type AnswerSet = ScoreAnswer<L>

The answers of the set, with the shape of the set.

Auto Trait Implementations§

§

impl<L> Forget for Score<L>

§

impl<L> Freeze for Score<L>
where Table<(&'static str, L), Entry<L>>: Freeze,

§

impl<L> Move for Score<L>

§

impl<L> RefUnwindSafe for Score<L>
where Table<(&'static str, L), Entry<L>>: RefUnwindSafe,

§

impl<L> Send for Score<L>
where Table<(&'static str, L), Entry<L>>: Send,

§

impl<L> Sync for Score<L>
where Table<(&'static str, L), Entry<L>>: Sync,

§

impl<L> Unpin for Score<L>
where Table<(&'static str, L), Entry<L>>: Unpin,

§

impl<L> UnsafeUnpin for Score<L>
where Table<(&'static str, L), Entry<L>>: UnsafeUnpin,

§

impl<L> UnwindSafe for Score<L>
where Table<(&'static str, L), Entry<L>>: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<Q> Ask for Q
where Q: QuestionSet,

Source§

fn ask<S: Serialize + ?Sized>(self, state: &S) -> AskFuture<Self> ⓘ

Asks the set about a state, with the global client. Read more
Source§

fn ask_with_receipt<S: Serialize + ?Sized>( self, state: &S, ) -> AskWithReceiptFuture<Self> ⓘ

Asks the set about a state, and returns a Receipt next to the answers. Read more
Source§

fn tag<T>(self, tag: T) -> Tagged<Self, T>

Puts a tag next to the set, so that the answers come back next to it. Read more
Source§

impl<Q> Ask for Q
where Q: QuestionSet,

Source§

fn ask<S: Serialize + ?Sized>( self, state: &S, ) -> Result<Self::AnswerSet, AskError>

Asks the set about a state, with the global client, and waits for the answers. Read more
Source§

fn ask_with_receipt<S: Serialize + ?Sized>( self, state: &S, ) -> Result<(Self::AnswerSet, Receipt), AskError>

Asks the set about a state, and returns a Receipt next to the answers. Read more
Source§

fn tag<T>(self, tag: T) -> Tagged<Self, T>

Puts a tag next to the set, so that the answers come back next to it. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more