rustpython_vm/function/
either.rs1use crate::{
2 convert::ToPyObject, AsObject, PyObject, PyObjectRef, PyResult, TryFromObject, VirtualMachine,
3};
4use std::borrow::Borrow;
5
6pub enum Either<A, B> {
7 A(A),
8 B(B),
9}
10
11impl<A: Borrow<PyObject>, B: Borrow<PyObject>> Borrow<PyObject> for Either<A, B> {
12 #[inline(always)]
13 fn borrow(&self) -> &PyObject {
14 match self {
15 Self::A(a) => a.borrow(),
16 Self::B(b) => b.borrow(),
17 }
18 }
19}
20
21impl<A: AsRef<PyObject>, B: AsRef<PyObject>> AsRef<PyObject> for Either<A, B> {
22 #[inline(always)]
23 fn as_ref(&self) -> &PyObject {
24 match self {
25 Self::A(a) => a.as_ref(),
26 Self::B(b) => b.as_ref(),
27 }
28 }
29}
30
31impl<A: Into<PyObjectRef>, B: Into<PyObjectRef>> From<Either<A, B>> for PyObjectRef {
32 #[inline(always)]
33 fn from(value: Either<A, B>) -> Self {
34 match value {
35 Either::A(a) => a.into(),
36 Either::B(b) => b.into(),
37 }
38 }
39}
40
41impl<A: ToPyObject, B: ToPyObject> ToPyObject for Either<A, B> {
42 #[inline(always)]
43 fn to_pyobject(self, vm: &VirtualMachine) -> PyObjectRef {
44 match self {
45 Self::A(a) => a.to_pyobject(vm),
46 Self::B(b) => b.to_pyobject(vm),
47 }
48 }
49}
50
51impl<A, B> TryFromObject for Either<A, B>
73where
74 A: TryFromObject,
75 B: TryFromObject,
76{
77 fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
78 A::try_from_object(vm, obj.clone())
79 .map(Either::A)
80 .or_else(|_| B::try_from_object(vm, obj.clone()).map(Either::B))
81 .map_err(|_| vm.new_type_error(format!("unexpected type {}", obj.class())))
82 }
83}