1use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
10pub struct Refrain {
11 pub name: String,
12 pub territorialize: Option<Pattern>,
13 pub deterritorialize: Option<Pattern>,
14 pub reterritorialize: Option<Pattern>,
15}
16
17#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
18pub enum Pattern {
19 Op(Op),
20 Seq(Vec<Pattern>),
21}
22
23#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
24pub enum Op {
25 Note { pitch: String, dur: String },
26 Loop { count: u32, body: Box<Pattern> },
27 Diff { x: String, t: String },
28 Quotient { rels: Vec<String> },
29 Sym(String),
30 Call { head: String, args: Vec<Pattern> },
31}
32
33impl Refrain {
34 pub fn new(name: impl Into<String>) -> Self {
35 Self {
36 name: name.into(),
37 territorialize: None,
38 deterritorialize: None,
39 reterritorialize: None,
40 }
41 }
42
43 pub fn stages(&self) -> impl Iterator<Item = (StageKind, &Pattern)> {
44 let t = self
45 .territorialize
46 .as_ref()
47 .map(|p| (StageKind::Territorialize, p));
48 let d = self
49 .deterritorialize
50 .as_ref()
51 .map(|p| (StageKind::Deterritorialize, p));
52 let r = self
53 .reterritorialize
54 .as_ref()
55 .map(|p| (StageKind::Reterritorialize, p));
56 t.into_iter().chain(d).chain(r)
57 }
58}
59
60#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
61pub enum StageKind {
62 Territorialize,
63 Deterritorialize,
64 Reterritorialize,
65}
66
67impl StageKind {
68 pub fn as_str(self) -> &'static str {
69 match self {
70 StageKind::Territorialize => "territorialize",
71 StageKind::Deterritorialize => "deterritorialize",
72 StageKind::Reterritorialize => "reterritorialize",
73 }
74 }
75}