summaryrefslogtreecommitdiff
path: root/pint/delegates/txt_defparser/block.py
blob: e8d8aa43f701ccf9dc23d7beaa66441db42e9cf6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
"""
    pint.delegates.txt_defparser.block
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Classes for Pint Blocks, which are defined by:

        @<block name>
            <content>
        @end

    :copyright: 2022 by Pint Authors, see AUTHORS for more details.
    :license: BSD, see LICENSE for more details.
"""


from __future__ import annotations

from dataclasses import dataclass

from typing import Generic, TypeVar

from ..base_defparser import PintParsedStatement, ParserConfig
from ..._vendor import flexparser as fp


@dataclass(frozen=True)
class EndDirectiveBlock(PintParsedStatement):
    """An EndDirectiveBlock is simply an "@end" statement."""

    @classmethod
    def from_string(cls, s: str) -> fp.FromString[EndDirectiveBlock]:
        if s == "@end":
            return cls()
        return None


OPST = TypeVar("OPST", bound="PintParsedStatement")
IPST = TypeVar("IPST", bound="PintParsedStatement")

DefT = TypeVar("DefT")


@dataclass(frozen=True)
class DirectiveBlock(
    Generic[DefT, OPST, IPST], fp.Block[OPST, IPST, EndDirectiveBlock, ParserConfig]
):
    """Directive blocks have beginning statement starting with a @ character.
    and ending with a "@end" (captured using a EndDirectiveBlock).

    Subclass this class for convenience.
    """

    closing: EndDirectiveBlock

    def derive_definition(self) -> DefT:
        ...