referrerpolicy=no-referrer-when-downgrade

frame_support/traits/tokens/imbalance/
signed_imbalance.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Convenience type for managing an imbalance whose sign is unknown.
19
20use super::super::imbalance::Imbalance;
21use crate::traits::misc::SameOrOther;
22use codec::FullCodec;
23use core::fmt::Debug;
24use sp_runtime::traits::{AtLeast32BitUnsigned, MaybeSerializeDeserialize};
25
26/// Either a positive or a negative imbalance.
27pub enum SignedImbalance<B, PositiveImbalance: Imbalance<B>> {
28	/// A positive imbalance (funds have been created but none destroyed).
29	Positive(PositiveImbalance),
30	/// A negative imbalance (funds have been destroyed but none created).
31	Negative(PositiveImbalance::Opposite),
32}
33
34impl<
35		P: Imbalance<B, Opposite = N>,
36		N: Imbalance<B, Opposite = P>,
37		B: AtLeast32BitUnsigned + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default,
38	> SignedImbalance<B, P>
39{
40	/// Create a `Positive` instance of `Self` whose value is zero.
41	pub fn zero() -> Self {
42		SignedImbalance::Positive(P::zero())
43	}
44
45	/// Drop `Self` if and only if it is equal to zero. Return `Err` with `Self` if not.
46	pub fn drop_zero(self) -> Result<(), Self> {
47		match self {
48			SignedImbalance::Positive(x) => x.drop_zero().map_err(SignedImbalance::Positive),
49			SignedImbalance::Negative(x) => x.drop_zero().map_err(SignedImbalance::Negative),
50		}
51	}
52
53	/// Consume `self` and an `other` to return a new instance that combines
54	/// both.
55	pub fn merge(self, other: Self) -> Self {
56		match (self, other) {
57			(SignedImbalance::Positive(one), SignedImbalance::Positive(other)) =>
58				SignedImbalance::Positive(one.merge(other)),
59			(SignedImbalance::Negative(one), SignedImbalance::Negative(other)) =>
60				SignedImbalance::Negative(one.merge(other)),
61			(SignedImbalance::Positive(one), SignedImbalance::Negative(other)) => {
62				match one.offset(other) {
63					SameOrOther::Same(positive) => SignedImbalance::Positive(positive),
64					SameOrOther::Other(negative) => SignedImbalance::Negative(negative),
65					SameOrOther::None => SignedImbalance::Positive(P::zero()),
66				}
67			},
68			(one, other) => other.merge(one),
69		}
70	}
71}