kotlin_poet_rs/spec/
generic_parameter.rs1use crate::spec::{CodeBlock, GenericInvariance, Name, Type};
2use crate::tokens;
3
4#[derive(Debug, Clone)]
8pub struct GenericParameter {
9 name: Name,
10 invariance: Option<GenericInvariance>,
12 type_boundaries: Vec<Type>,
13}
14
15impl GenericParameter {
16 pub fn new<NameLike: Into<Name>>(name: NameLike) -> Self {
18 GenericParameter {
19 name: name.into(),
20 invariance: None,
21 type_boundaries: Vec::new(),
22 }
23 }
24
25 pub fn invariance(mut self, invariance: GenericInvariance) -> Self {
27 self.invariance = Some(invariance);
28 self
29 }
30
31 pub fn type_boundary<TypeLike: Into<Type>>(mut self, boundary: TypeLike) -> Self {
34 self.type_boundaries.push(boundary.into());
35 self
36 }
37
38 pub(crate) fn render_definition(&self) -> CodeBlock {
39 let mut code = CodeBlock::empty();
40 if let Some(invariance) = &self.invariance {
41 code.push_renderable(invariance);
42 code.push_space();
43 }
44 code.push_renderable(&self.name);
45 code
46 }
47
48 pub(crate) fn render_type_boundaries(&self) -> CodeBlock {
49 let mut code = CodeBlock::empty();
50 code.push_comma_separated(
51 &self.type_boundaries.iter().map(|boundary| {
52 let mut inner = CodeBlock::empty();
53 inner.push_renderable(&self.name);
54 inner.push_static_atom(tokens::COLON);
55 inner.push_space();
56 inner.push_renderable(boundary);
57 inner
58 }).collect::<Vec<CodeBlock>>()
59 );
60 code
61 }
62
63 pub(crate) fn render_type_boundaries_vec_if_required(vec: &[GenericParameter]) -> CodeBlock {
64 let boundary_code_blocks = vec.iter().filter(|parameter| !parameter.type_boundaries.is_empty())
65 .map(|parameter| {
66 parameter.render_type_boundaries()
67 })
68 .collect::<Vec<CodeBlock>>();
69
70 if boundary_code_blocks.is_empty() {
71 return CodeBlock::empty();
72 }
73
74 let mut code = CodeBlock::empty();
75 code.push_static_atom(tokens::keyword::WHERE);
76 code.push_space();
77 code.push_comma_separated(&boundary_code_blocks);
78 code.push_space();
79
80 code
81 }
82}