abi_stable_derive/sabi_trait/
method_where_clause.rs

1use super::*;
2
3use as_derive_utils::spanned_err;
4
5use quote::ToTokens;
6
7use syn::{WhereClause, WherePredicate};
8
9use crate::utils::{LinearResult, SynResultExt};
10
11/// Parses and prints the syntactically valid where clauses in object safe traits.
12#[derive(Debug, Default, Clone, PartialEq, Eq)]
13pub(crate) struct MethodWhereClause<'a> {
14    pub requires_self_sized: bool,
15    _marker: PhantomData<&'a ()>,
16}
17
18impl<'a> MethodWhereClause<'a> {
19    pub fn new(where_: &'a WhereClause, ctokens: &'a CommonTokens) -> Result<Self, syn::Error> {
20        let mut this = MethodWhereClause::default();
21        let mut error = LinearResult::ok(());
22
23        for predicate in &where_.predicates {
24            match predicate {
25                WherePredicate::Type(ty_pred) => {
26                    if ty_pred.bounds.is_empty() {
27                        error.push_err(spanned_err!(predicate, "The bounds are empty"));
28                    }
29                    if ty_pred.bounded_ty == ctokens.self_ty
30                        && ty_pred.bounds[0] == ctokens.sized_bound
31                    {
32                        this.requires_self_sized = true;
33                    } else {
34                        error.push_err(spanned_err!(predicate, "This bound is not supported"));
35                    }
36                }
37                WherePredicate::Lifetime { .. } => {
38                    error.push_err(spanned_err!(
39                        predicate,
40                        "Lifetime constraints are not currently supported"
41                    ));
42                }
43                WherePredicate::Eq { .. } => {
44                    error.push_err(spanned_err!(
45                        predicate,
46                        "Type equality constraints are not currently supported",
47                    ));
48                }
49            }
50        }
51        error.into_result().map(|_| this)
52    }
53
54    pub fn get_tokenizer(&self, ctokens: &'a CommonTokens) -> MethodWhereClauseTokenizer<'_> {
55        MethodWhereClauseTokenizer {
56            where_clause: self,
57            ctokens,
58        }
59    }
60}
61
62#[derive(Debug, Clone, PartialEq, Eq)]
63pub(crate) struct MethodWhereClauseTokenizer<'a> {
64    where_clause: &'a MethodWhereClause<'a>,
65    ctokens: &'a CommonTokens,
66}
67
68impl<'a> ToTokens for MethodWhereClauseTokenizer<'a> {
69    fn to_tokens(&self, ts: &mut TokenStream2) {
70        let where_clause = self.where_clause;
71        let ctokens = self.ctokens;
72
73        if where_clause.requires_self_sized {
74            ctokens.self_sized.to_tokens(ts);
75        }
76    }
77}