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#[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}