Struct copper::Model

source ·
pub struct Model { /* private fields */ }
Expand description

Library entry point used to declare decision variables and constraints, and configure search.

Optimization problems are modeled with base decision variables and derived expressions. You can use constraints to restrict which values are considered valid assignments. An assignment that satisfies all constraints is called “feasible”. Once all decision variables and constraints have been declared, call one of the following:

  • solve: get the first feasible assignment
  • enumerate: iterate over all feasible assignments
  • minimize: find the assignment that minimizes the provided expression
  • maximize: find the assignment that maximizes the provided expression
  • minimize_and_iterate: iterate over feasible assignments while minimizing an expression
  • maximize_and_iterate: iterate over feasible assignments while maximizing an expression

Here is an example to describe how a typical model is formulated. It is a rendition of a combinatorial optimization classic: the Knapsack problem.

Let’s say we are building a brand new PC. We want to play AAA games without going bankrupt.

// All problem formulations will start with a model object
let mut m = copper::Model::default();

Variables and expressions

Decision variables represent a decision: they are declared with a domain.

// How many monitors do we buy: we need at least one, but not more than three
let n_monitors = m.new_var(1, 3).unwrap();

// All monitors cost the same, and each additional monitor provides the same bump to our score
let monitor_price = 100;
let monitor_score = 250;

// Each GPU model has a fixed price, and an associated benchmark score
let gpu_prices = [150, 250, 500];
let gpu_scores = [100, 400, 800];

// We use binary decision variables to represent "do I pick this GPU?"
let gpus: Vec<_> = m.new_vars_binary(gpu_scores.len()).collect();

Using variables as building blocks, we can create expressions to represent other quantities.


// Extension trait, used here to scale our decision variables by a constant (`times` method)
use copper::views::ViewExt;

// For each potential GPU, we multiply its price (and score) by whether or not it is selected.
// The sum of these terms gives us the price and score of the selected GPU.
let gpu_price = m.sum_iter(gpus.iter().zip(gpu_prices).map(|(x, price)| x.times(price)));
let gpu_score = m.sum_iter(gpus.iter().zip(gpu_scores).map(|(x, score)| x.times(score)));

// This expression is the overall price of our build
let price = m.add(gpu_price, n_monitors.times(monitor_price));

// We want to maximize this score: how much we'll value this particular build
let score = m.add(gpu_score, n_monitors.times(monitor_score));

Constraints

Constraints establish relationships between variables, and restrict feasible values.

// Exactly one GPU: we want to run Crysis, but our case must fit under the desk
let n_gpus = m.sum(&gpus);
m.equals(n_gpus, 1);

// Grandma got us some money for our birthday, that will be our budget
m.less_than_or_equals(price, 600);

Search

While constraints define feasibility, objectives are soft: they only determine optimality.

// Let the solver find the assignment that upholds our constraints and maximizes our score
let solution = m.maximize(score).unwrap();

// Our optimal build has three monitors and a mid-tier GPU. We even have some left-over cash!
assert_eq!(solution[n_monitors], 3);
assert_eq!(solution.get_values_binary(&gpus), vec![false, true, false]);
assert_eq!(solution[score], 1150);
assert_eq!(solution[price], 550);

Find the full code in the examples directory.

Implementations§

source§

impl Model

source

pub fn new_var(&mut self, min: i32, max: i32) -> Option<VarId>

Create a new integer decision variable, with the provided domain bounds.

Both lower and upper bounds are included in the domain. This function will only create a decision variable if min < max.

Examples found in repository?
examples/pc.rs (line 14)
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
fn main() {
    // All problem formulations will start with a model object
    let mut m = copper::Model::default();

    // How many monitors do we buy: we need at least one, but not more than three
    let n_monitors = m.new_var(1, 3).unwrap();

    // All monitors cost the same, and each additional monitor provides the same bump to our score
    let monitor_price = 100;
    let monitor_score = 250;

    // Each GPU model has a fixed price, and an associated benchmark score
    let gpu_prices = [150, 250, 500];
    let gpu_scores = [100, 400, 800];

    // We use binary decision variables to represent "do I pick this GPU?"
    let gpus: Vec<_> = m.new_vars_binary(gpu_scores.len()).collect();

    // For each potential GPU, we multiply its price (and score) by whether or not it is selected.
    // The sum of these terms gives us the price and score of the selected GPU.
    let gpu_price = m.sum_iter(gpus.iter().zip(gpu_prices).map(|(x, price)| x.times(price)));
    let gpu_score = m.sum_iter(gpus.iter().zip(gpu_scores).map(|(x, score)| x.times(score)));

    // This expression is the overall price of our build
    let price = m.add(gpu_price, n_monitors.times(monitor_price));

    // We want to maximize this score: how much we'll value this particular build
    let score = m.add(gpu_score, n_monitors.times(monitor_score));

    // Exactly one GPU: we want to run Crysis, but our case must fit under the desk
    let n_gpus = m.sum(&gpus);
    m.equals(n_gpus, 1);

    // Grandma got us some money for our birthday, that will be our budget
    m.less_than_or_equals(price, 600);

    // Let the solver find the assignment that upholds our constraints and maximizes our score
    let solution = m.maximize(score).unwrap();

    // Our optimal build has three monitors and a mid-tier GPU. We even have some left-over cash!
    assert_eq!(solution[n_monitors], 3);
    assert_eq!(solution.get_values_binary(&gpus), vec![false, true, false]);
    assert_eq!(solution[score], 1150);
    assert_eq!(solution[price], 550);
}
source

pub fn new_vars( &mut self, n: usize, min: i32, max: i32 ) -> Option<impl Iterator<Item = VarId> + '_>

Create new integer decision variables, with the provided domain bounds.

All created variables will have the same starting domain bounds. Both lower and upper bounds are included in the domain. This function will only create decision variables if min < max.

source

pub fn new_var_binary(&mut self) -> VarIdBinary

Create a new binary decision variable.

source

pub fn new_vars_binary( &mut self, n: usize ) -> impl Iterator<Item = VarIdBinary> + '_

Create new binary decision variables.

Examples found in repository?
examples/pc.rs (line 25)
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
fn main() {
    // All problem formulations will start with a model object
    let mut m = copper::Model::default();

    // How many monitors do we buy: we need at least one, but not more than three
    let n_monitors = m.new_var(1, 3).unwrap();

    // All monitors cost the same, and each additional monitor provides the same bump to our score
    let monitor_price = 100;
    let monitor_score = 250;

    // Each GPU model has a fixed price, and an associated benchmark score
    let gpu_prices = [150, 250, 500];
    let gpu_scores = [100, 400, 800];

    // We use binary decision variables to represent "do I pick this GPU?"
    let gpus: Vec<_> = m.new_vars_binary(gpu_scores.len()).collect();

    // For each potential GPU, we multiply its price (and score) by whether or not it is selected.
    // The sum of these terms gives us the price and score of the selected GPU.
    let gpu_price = m.sum_iter(gpus.iter().zip(gpu_prices).map(|(x, price)| x.times(price)));
    let gpu_score = m.sum_iter(gpus.iter().zip(gpu_scores).map(|(x, score)| x.times(score)));

    // This expression is the overall price of our build
    let price = m.add(gpu_price, n_monitors.times(monitor_price));

    // We want to maximize this score: how much we'll value this particular build
    let score = m.add(gpu_score, n_monitors.times(monitor_score));

    // Exactly one GPU: we want to run Crysis, but our case must fit under the desk
    let n_gpus = m.sum(&gpus);
    m.equals(n_gpus, 1);

    // Grandma got us some money for our birthday, that will be our budget
    m.less_than_or_equals(price, 600);

    // Let the solver find the assignment that upholds our constraints and maximizes our score
    let solution = m.maximize(score).unwrap();

    // Our optimal build has three monitors and a mid-tier GPU. We even have some left-over cash!
    assert_eq!(solution[n_monitors], 3);
    assert_eq!(solution.get_values_binary(&gpus), vec![false, true, false]);
    assert_eq!(solution[score], 1150);
    assert_eq!(solution[price], 550);
}
source

pub fn add(&mut self, x: impl View, y: impl View) -> VarId

Create an expression of two views added together.

Examples found in repository?
examples/pc.rs (line 33)
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
fn main() {
    // All problem formulations will start with a model object
    let mut m = copper::Model::default();

    // How many monitors do we buy: we need at least one, but not more than three
    let n_monitors = m.new_var(1, 3).unwrap();

    // All monitors cost the same, and each additional monitor provides the same bump to our score
    let monitor_price = 100;
    let monitor_score = 250;

    // Each GPU model has a fixed price, and an associated benchmark score
    let gpu_prices = [150, 250, 500];
    let gpu_scores = [100, 400, 800];

    // We use binary decision variables to represent "do I pick this GPU?"
    let gpus: Vec<_> = m.new_vars_binary(gpu_scores.len()).collect();

    // For each potential GPU, we multiply its price (and score) by whether or not it is selected.
    // The sum of these terms gives us the price and score of the selected GPU.
    let gpu_price = m.sum_iter(gpus.iter().zip(gpu_prices).map(|(x, price)| x.times(price)));
    let gpu_score = m.sum_iter(gpus.iter().zip(gpu_scores).map(|(x, score)| x.times(score)));

    // This expression is the overall price of our build
    let price = m.add(gpu_price, n_monitors.times(monitor_price));

    // We want to maximize this score: how much we'll value this particular build
    let score = m.add(gpu_score, n_monitors.times(monitor_score));

    // Exactly one GPU: we want to run Crysis, but our case must fit under the desk
    let n_gpus = m.sum(&gpus);
    m.equals(n_gpus, 1);

    // Grandma got us some money for our birthday, that will be our budget
    m.less_than_or_equals(price, 600);

    // Let the solver find the assignment that upholds our constraints and maximizes our score
    let solution = m.maximize(score).unwrap();

    // Our optimal build has three monitors and a mid-tier GPU. We even have some left-over cash!
    assert_eq!(solution[n_monitors], 3);
    assert_eq!(solution.get_values_binary(&gpus), vec![false, true, false]);
    assert_eq!(solution[score], 1150);
    assert_eq!(solution[price], 550);
}
source

pub fn sum(&mut self, xs: &[impl View]) -> VarId

Create an expression of the sum of a slice of views.

Examples found in repository?
examples/pc.rs (line 39)
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
fn main() {
    // All problem formulations will start with a model object
    let mut m = copper::Model::default();

    // How many monitors do we buy: we need at least one, but not more than three
    let n_monitors = m.new_var(1, 3).unwrap();

    // All monitors cost the same, and each additional monitor provides the same bump to our score
    let monitor_price = 100;
    let monitor_score = 250;

    // Each GPU model has a fixed price, and an associated benchmark score
    let gpu_prices = [150, 250, 500];
    let gpu_scores = [100, 400, 800];

    // We use binary decision variables to represent "do I pick this GPU?"
    let gpus: Vec<_> = m.new_vars_binary(gpu_scores.len()).collect();

    // For each potential GPU, we multiply its price (and score) by whether or not it is selected.
    // The sum of these terms gives us the price and score of the selected GPU.
    let gpu_price = m.sum_iter(gpus.iter().zip(gpu_prices).map(|(x, price)| x.times(price)));
    let gpu_score = m.sum_iter(gpus.iter().zip(gpu_scores).map(|(x, score)| x.times(score)));

    // This expression is the overall price of our build
    let price = m.add(gpu_price, n_monitors.times(monitor_price));

    // We want to maximize this score: how much we'll value this particular build
    let score = m.add(gpu_score, n_monitors.times(monitor_score));

    // Exactly one GPU: we want to run Crysis, but our case must fit under the desk
    let n_gpus = m.sum(&gpus);
    m.equals(n_gpus, 1);

    // Grandma got us some money for our birthday, that will be our budget
    m.less_than_or_equals(price, 600);

    // Let the solver find the assignment that upholds our constraints and maximizes our score
    let solution = m.maximize(score).unwrap();

    // Our optimal build has three monitors and a mid-tier GPU. We even have some left-over cash!
    assert_eq!(solution[n_monitors], 3);
    assert_eq!(solution.get_values_binary(&gpus), vec![false, true, false]);
    assert_eq!(solution[score], 1150);
    assert_eq!(solution[price], 550);
}
source

pub fn sum_iter(&mut self, xs: impl IntoIterator<Item = impl View>) -> VarId

Create an expression of the sum of an iterator of views.

Examples found in repository?
examples/pc.rs (line 29)
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
fn main() {
    // All problem formulations will start with a model object
    let mut m = copper::Model::default();

    // How many monitors do we buy: we need at least one, but not more than three
    let n_monitors = m.new_var(1, 3).unwrap();

    // All monitors cost the same, and each additional monitor provides the same bump to our score
    let monitor_price = 100;
    let monitor_score = 250;

    // Each GPU model has a fixed price, and an associated benchmark score
    let gpu_prices = [150, 250, 500];
    let gpu_scores = [100, 400, 800];

    // We use binary decision variables to represent "do I pick this GPU?"
    let gpus: Vec<_> = m.new_vars_binary(gpu_scores.len()).collect();

    // For each potential GPU, we multiply its price (and score) by whether or not it is selected.
    // The sum of these terms gives us the price and score of the selected GPU.
    let gpu_price = m.sum_iter(gpus.iter().zip(gpu_prices).map(|(x, price)| x.times(price)));
    let gpu_score = m.sum_iter(gpus.iter().zip(gpu_scores).map(|(x, score)| x.times(score)));

    // This expression is the overall price of our build
    let price = m.add(gpu_price, n_monitors.times(monitor_price));

    // We want to maximize this score: how much we'll value this particular build
    let score = m.add(gpu_score, n_monitors.times(monitor_score));

    // Exactly one GPU: we want to run Crysis, but our case must fit under the desk
    let n_gpus = m.sum(&gpus);
    m.equals(n_gpus, 1);

    // Grandma got us some money for our birthday, that will be our budget
    m.less_than_or_equals(price, 600);

    // Let the solver find the assignment that upholds our constraints and maximizes our score
    let solution = m.maximize(score).unwrap();

    // Our optimal build has three monitors and a mid-tier GPU. We even have some left-over cash!
    assert_eq!(solution[n_monitors], 3);
    assert_eq!(solution.get_values_binary(&gpus), vec![false, true, false]);
    assert_eq!(solution[score], 1150);
    assert_eq!(solution[price], 550);
}
source

pub fn equals(&mut self, x: impl View, y: impl View)

Declare two expressions to be equal.

Examples found in repository?
examples/pc.rs (line 40)
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
fn main() {
    // All problem formulations will start with a model object
    let mut m = copper::Model::default();

    // How many monitors do we buy: we need at least one, but not more than three
    let n_monitors = m.new_var(1, 3).unwrap();

    // All monitors cost the same, and each additional monitor provides the same bump to our score
    let monitor_price = 100;
    let monitor_score = 250;

    // Each GPU model has a fixed price, and an associated benchmark score
    let gpu_prices = [150, 250, 500];
    let gpu_scores = [100, 400, 800];

    // We use binary decision variables to represent "do I pick this GPU?"
    let gpus: Vec<_> = m.new_vars_binary(gpu_scores.len()).collect();

    // For each potential GPU, we multiply its price (and score) by whether or not it is selected.
    // The sum of these terms gives us the price and score of the selected GPU.
    let gpu_price = m.sum_iter(gpus.iter().zip(gpu_prices).map(|(x, price)| x.times(price)));
    let gpu_score = m.sum_iter(gpus.iter().zip(gpu_scores).map(|(x, score)| x.times(score)));

    // This expression is the overall price of our build
    let price = m.add(gpu_price, n_monitors.times(monitor_price));

    // We want to maximize this score: how much we'll value this particular build
    let score = m.add(gpu_score, n_monitors.times(monitor_score));

    // Exactly one GPU: we want to run Crysis, but our case must fit under the desk
    let n_gpus = m.sum(&gpus);
    m.equals(n_gpus, 1);

    // Grandma got us some money for our birthday, that will be our budget
    m.less_than_or_equals(price, 600);

    // Let the solver find the assignment that upholds our constraints and maximizes our score
    let solution = m.maximize(score).unwrap();

    // Our optimal build has three monitors and a mid-tier GPU. We even have some left-over cash!
    assert_eq!(solution[n_monitors], 3);
    assert_eq!(solution.get_values_binary(&gpus), vec![false, true, false]);
    assert_eq!(solution[score], 1150);
    assert_eq!(solution[price], 550);
}
source

pub fn less_than_or_equals(&mut self, x: impl View, y: impl View)

Declare constraint x <= y.

Examples found in repository?
examples/pc.rs (line 43)
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
fn main() {
    // All problem formulations will start with a model object
    let mut m = copper::Model::default();

    // How many monitors do we buy: we need at least one, but not more than three
    let n_monitors = m.new_var(1, 3).unwrap();

    // All monitors cost the same, and each additional monitor provides the same bump to our score
    let monitor_price = 100;
    let monitor_score = 250;

    // Each GPU model has a fixed price, and an associated benchmark score
    let gpu_prices = [150, 250, 500];
    let gpu_scores = [100, 400, 800];

    // We use binary decision variables to represent "do I pick this GPU?"
    let gpus: Vec<_> = m.new_vars_binary(gpu_scores.len()).collect();

    // For each potential GPU, we multiply its price (and score) by whether or not it is selected.
    // The sum of these terms gives us the price and score of the selected GPU.
    let gpu_price = m.sum_iter(gpus.iter().zip(gpu_prices).map(|(x, price)| x.times(price)));
    let gpu_score = m.sum_iter(gpus.iter().zip(gpu_scores).map(|(x, score)| x.times(score)));

    // This expression is the overall price of our build
    let price = m.add(gpu_price, n_monitors.times(monitor_price));

    // We want to maximize this score: how much we'll value this particular build
    let score = m.add(gpu_score, n_monitors.times(monitor_score));

    // Exactly one GPU: we want to run Crysis, but our case must fit under the desk
    let n_gpus = m.sum(&gpus);
    m.equals(n_gpus, 1);

    // Grandma got us some money for our birthday, that will be our budget
    m.less_than_or_equals(price, 600);

    // Let the solver find the assignment that upholds our constraints and maximizes our score
    let solution = m.maximize(score).unwrap();

    // Our optimal build has three monitors and a mid-tier GPU. We even have some left-over cash!
    assert_eq!(solution[n_monitors], 3);
    assert_eq!(solution.get_values_binary(&gpus), vec![false, true, false]);
    assert_eq!(solution[score], 1150);
    assert_eq!(solution[price], 550);
}
source

pub fn less_than(&mut self, x: impl View, y: impl View)

Declare constraint x < y.

source

pub fn greater_than_or_equals(&mut self, x: impl View, y: impl View)

Declare constraint x >= y.

source

pub fn greater_than(&mut self, x: impl View, y: impl View)

Declare constraint x > y.

source

pub fn minimize(self, objective: impl View) -> Option<Solution>

Find assignment that minimizes objective expression while satisfying all constraints.

source

pub fn minimize_and_iterate( self, objective: impl View ) -> impl Iterator<Item = Solution>

Enumerate assignments that satisfy all constraints, while minimizing objective expression.

The order in which assignments are yielded is not stable.

source

pub fn maximize(self, objective: impl View) -> Option<Solution>

Find assignment that maximizes objective expression while satisfying all constraints.

Examples found in repository?
examples/pc.rs (line 46)
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
fn main() {
    // All problem formulations will start with a model object
    let mut m = copper::Model::default();

    // How many monitors do we buy: we need at least one, but not more than three
    let n_monitors = m.new_var(1, 3).unwrap();

    // All monitors cost the same, and each additional monitor provides the same bump to our score
    let monitor_price = 100;
    let monitor_score = 250;

    // Each GPU model has a fixed price, and an associated benchmark score
    let gpu_prices = [150, 250, 500];
    let gpu_scores = [100, 400, 800];

    // We use binary decision variables to represent "do I pick this GPU?"
    let gpus: Vec<_> = m.new_vars_binary(gpu_scores.len()).collect();

    // For each potential GPU, we multiply its price (and score) by whether or not it is selected.
    // The sum of these terms gives us the price and score of the selected GPU.
    let gpu_price = m.sum_iter(gpus.iter().zip(gpu_prices).map(|(x, price)| x.times(price)));
    let gpu_score = m.sum_iter(gpus.iter().zip(gpu_scores).map(|(x, score)| x.times(score)));

    // This expression is the overall price of our build
    let price = m.add(gpu_price, n_monitors.times(monitor_price));

    // We want to maximize this score: how much we'll value this particular build
    let score = m.add(gpu_score, n_monitors.times(monitor_score));

    // Exactly one GPU: we want to run Crysis, but our case must fit under the desk
    let n_gpus = m.sum(&gpus);
    m.equals(n_gpus, 1);

    // Grandma got us some money for our birthday, that will be our budget
    m.less_than_or_equals(price, 600);

    // Let the solver find the assignment that upholds our constraints and maximizes our score
    let solution = m.maximize(score).unwrap();

    // Our optimal build has three monitors and a mid-tier GPU. We even have some left-over cash!
    assert_eq!(solution[n_monitors], 3);
    assert_eq!(solution.get_values_binary(&gpus), vec![false, true, false]);
    assert_eq!(solution[score], 1150);
    assert_eq!(solution[price], 550);
}
source

pub fn maximize_and_iterate( self, objective: impl View ) -> impl Iterator<Item = Solution>

Enumerate assignments that satisfy all constraints, while maximizing objective expression.

The order in which assignments are yielded is not stable.

source

pub fn solve(self) -> Option<Solution>

Search for assignment that satisfies all constraints within bounds of decision variables.

source

pub fn enumerate(self) -> impl Iterator<Item = Solution>

Enumerate all assignments that satisfy all constraints.

The order in which assignments are yielded is not stable.

Trait Implementations§

source§

impl Debug for Model

source§

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

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

impl Default for Model

source§

fn default() -> Model

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for Model

§

impl !Send for Model

§

impl !Sync for Model

§

impl Unpin for Model

§

impl !UnwindSafe for Model

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<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> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

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, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.