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}