Skip to main content

tvm_ffi/extra/
dispatch.rs

1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements.  See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership.  The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License.  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,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied.  See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20//! Typed callback dispatch for [`super::structural_visit::structural_walk`].
21
22use crate::error::Result;
23
24use super::structural_visit::{DefRegionKind, IntoWalker, NativeVisit, StructuralView, WalkResult};
25
26/// Dispatch for typed `structural_walk` observer callbacks.
27///
28/// `None` means that no handler matched. `#[dispatch(walk)]` generates this
29/// trait from source-ordered `walk_*` methods.
30pub trait WalkDispatch: Sized {
31    fn dispatch_walk(
32        &mut self,
33        value: &StructuralView,
34        def_region_kind: DefRegionKind,
35    ) -> Option<Result<WalkResult>>;
36}
37
38impl<V: WalkDispatch> WalkDispatch for &mut V {
39    #[inline]
40    fn dispatch_walk(
41        &mut self,
42        value: &StructuralView,
43        def_region_kind: DefRegionKind,
44    ) -> Option<Result<WalkResult>> {
45        (**self).dispatch_walk(value, def_region_kind)
46    }
47}
48
49#[doc(hidden)]
50pub enum ByWalkDispatch {}
51
52impl<'a, V: WalkDispatch> IntoWalker<ByWalkDispatch> for &'a mut V {
53    type Walker = DispatchWalker<&'a mut V>;
54    fn into_walker(self) -> Self::Walker {
55        DispatchWalker { walker: self }
56    }
57}
58
59/// Adapter from [`WalkDispatch`] to the traversal's native callback.
60#[doc(hidden)]
61pub struct DispatchWalker<V> {
62    walker: V,
63}
64
65impl<V: WalkDispatch> NativeVisit for DispatchWalker<V> {
66    fn visit(
67        &mut self,
68        value: &StructuralView,
69        def_region_kind: DefRegionKind,
70    ) -> Result<WalkResult> {
71        self.walker
72            .dispatch_walk(value, def_region_kind)
73            .unwrap_or_else(|| Ok(WalkResult::Advance))
74    }
75}