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::{
25 DefRegionKind, IntoWalker, NativeVisit, VisitValue, WalkCallbackResult, WalkResult,
26};
27
28/// Dispatch for typed `structural_walk` observer callbacks.
29///
30/// `None` means that no handler matched. `#[dispatch(walk)]` generates this
31/// trait from source-ordered `walk_*` methods.
32pub trait WalkDispatch: Sized {
33 fn dispatch_walk(
34 &mut self,
35 value: &VisitValue,
36 def_region_kind: DefRegionKind,
37 ) -> Option<WalkCallbackResult>;
38}
39
40impl<V: WalkDispatch> WalkDispatch for &mut V {
41 #[inline]
42 fn dispatch_walk(
43 &mut self,
44 value: &VisitValue,
45 def_region_kind: DefRegionKind,
46 ) -> Option<WalkCallbackResult> {
47 (**self).dispatch_walk(value, def_region_kind)
48 }
49}
50
51#[doc(hidden)]
52pub enum ByWalkDispatch {}
53
54impl<'a, V: WalkDispatch> IntoWalker<ByWalkDispatch> for &'a mut V {
55 type Walker = DispatchWalker<&'a mut V>;
56 fn into_walker(self) -> Self::Walker {
57 DispatchWalker { walker: self }
58 }
59}
60
61/// Adapter from [`WalkDispatch`] to the traversal's native callback.
62#[doc(hidden)]
63pub struct DispatchWalker<V> {
64 walker: V,
65}
66
67impl<V: WalkDispatch> NativeVisit for DispatchWalker<V> {
68 fn visit(&mut self, value: &VisitValue, def_region_kind: DefRegionKind) -> Result<WalkResult> {
69 self.walker
70 .dispatch_walk(value, def_region_kind)
71 .unwrap_or(Ok(WalkResult::Advance))
72 }
73}