esl_compiler/builder/
need.rs

1//! Need builder module
2
3use std::rc::Rc;
4
5use crate::builder::subject::{build_some_subject, Subject};
6use crate::context::Context;
7use crate::cursor::{Cursor, Error, Token};
8use crate::location::FileLocation;
9use crate::parser::Rule;
10use crate::reference::{
11    BehaviorTarget, ComponentTarget, GoalTarget, ParameterTarget, Reference, RelationTarget,
12    TransformationTarget, VariableTarget,
13};
14
15/// Need or qualitative requirement.
16#[derive(Clone, Debug, PartialEq)]
17pub struct Need {
18    /// Need's name or label.
19    pub name: Token,
20    /// Complete need's textual location.
21    pub loc: FileLocation,
22    /// Need's subject.
23    pub subject: Reference<Subject, NeedSubject>,
24    /// Need's content.
25    pub content: Rc<str>,
26}
27impl std::fmt::Display for Need {
28    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29        write!(f, "{}", self.name)
30    }
31}
32
33/// Resolved need subject.
34#[derive(Clone, Debug, PartialEq)]
35pub enum NeedSubject {
36    Behavior(BehaviorTarget),
37    Component(ComponentTarget),
38    Goal(GoalTarget),
39    Parameter(ParameterTarget),
40    Relation(RelationTarget),
41    Transformation(TransformationTarget),
42    Variable(VariableTarget),
43}
44
45/// Build a need instance from a cursor.
46pub fn build_need_instantiation(
47    ctx: &mut Context,
48    need_instantiation: Cursor,
49) -> Result<Need, Error> {
50    let loc = need_instantiation.as_location();
51    let mut cs = need_instantiation.into_inner();
52    let name = cs
53        .req_first(Rule::some_label)?
54        .into_inner()
55        .req_first(Rule::some_name)?
56        .into();
57    let subject = cs
58        .req_first(Rule::some_subject)
59        .and_then(|c| build_some_subject(ctx, c))?
60        .into();
61    let content = cs.req_first(Rule::need_text)?.as_str().into();
62    Ok(Need {
63        name,
64        loc,
65        subject,
66        content,
67    })
68}