swayfmt/items/item_abi/
mod.rs

1use crate::{
2    comments::{rewrite_with_comments, write_comments},
3    constants::NEW_LINE,
4    formatter::*,
5    utils::{
6        map::byte_span::{ByteSpan, LeafSpans},
7        CurlyBrace,
8    },
9};
10use std::fmt::Write;
11use sway_ast::{
12    keywords::{AbiToken, ColonToken, Keyword, Token},
13    ItemAbi,
14};
15use sway_types::{ast::Delimiter, Spanned};
16
17#[cfg(test)]
18mod tests;
19
20impl Format for ItemAbi {
21    fn format(
22        &self,
23        formatted_code: &mut FormattedCode,
24        formatter: &mut Formatter,
25    ) -> Result<(), FormatterError> {
26        let start_len = formatted_code.len();
27        // `abi name`
28        write!(formatted_code, "{} ", AbiToken::AS_STR)?;
29        self.name.format(formatted_code, formatter)?;
30
31        // ` : super_trait + super_trait`
32        if let Some((_colon_token, traits)) = &self.super_traits {
33            write!(formatted_code, " {} ", ColonToken::AS_STR)?;
34            traits.format(formatted_code, formatter)?;
35        }
36
37        Self::open_curly_brace(formatted_code, formatter)?;
38
39        let abi_items = self.abi_items.get();
40
41        // abi_items
42        for trait_item in abi_items.iter() {
43            trait_item.format(formatted_code, formatter)?;
44            write!(formatted_code, "{NEW_LINE}")?;
45        }
46
47        if abi_items.is_empty() {
48            write_comments(
49                formatted_code,
50                self.abi_items.span().start()..self.abi_items.span().end(),
51                formatter,
52            )?;
53        }
54
55        Self::close_curly_brace(formatted_code, formatter)?;
56
57        // abi_defs_opt
58        if let Some(abi_defs) = self.abi_defs_opt.clone() {
59            Self::open_curly_brace(formatted_code, formatter)?;
60            for item in abi_defs.get().iter() {
61                item.format(formatted_code, formatter)?;
62                write!(formatted_code, "{NEW_LINE}")?;
63            }
64            if abi_defs.get().is_empty() {
65                write!(formatted_code, "{NEW_LINE}")?;
66            }
67            Self::close_curly_brace(formatted_code, formatter)?;
68        }
69
70        rewrite_with_comments::<ItemAbi>(
71            formatter,
72            self.span(),
73            self.leaf_spans(),
74            formatted_code,
75            start_len,
76        )?;
77
78        Ok(())
79    }
80}
81
82impl CurlyBrace for ItemAbi {
83    fn open_curly_brace(
84        line: &mut String,
85        formatter: &mut Formatter,
86    ) -> Result<(), FormatterError> {
87        formatter.indent();
88        let open_brace = Delimiter::Brace.as_open_char();
89        // Add opening brace to the same line
90        writeln!(line, " {open_brace}")?;
91
92        Ok(())
93    }
94    fn close_curly_brace(
95        line: &mut String,
96        formatter: &mut Formatter,
97    ) -> Result<(), FormatterError> {
98        // If shape is becoming left-most aligned or - indent just have the default shape
99        formatter.unindent();
100        write!(
101            line,
102            "{}{}",
103            formatter.indent_to_str()?,
104            Delimiter::Brace.as_close_char()
105        )?;
106
107        Ok(())
108    }
109}
110
111impl LeafSpans for ItemAbi {
112    fn leaf_spans(&self) -> Vec<ByteSpan> {
113        let mut collected_spans = vec![ByteSpan::from(self.abi_token.span())];
114        collected_spans.push(ByteSpan::from(self.name.span()));
115        collected_spans.append(&mut self.abi_items.leaf_spans());
116        if let Some(abi_defs) = &self.abi_defs_opt {
117            collected_spans.append(&mut abi_defs.leaf_spans());
118        }
119        collected_spans
120    }
121}