1 /** 2 * Copyright © Underground Rekordz 2019 3 * License: MIT (https://github.com/UndergroundRekordz/Musicpulator/blob/master/LICENSE) 4 * Author: Jacob Jensen (bausshf) 5 */ 6 module musicpulator.song; 7 8 import std..string : format; 9 10 import musicpulator.songpart; 11 import musicpulator.musicalscale; 12 import musicpulator.musicalprogression; 13 14 /// Wrapper around a song. 15 final class Song 16 { 17 private: 18 /// The name. 19 string _name; 20 21 /// The parts of the song. 22 SongPart[SongPartTitle] _parts; 23 24 public: 25 final: 26 /// Creates a new song. 27 this(string name) 28 { 29 _name = name; 30 } 31 32 @property 33 { 34 /// Gets the parts of a song. 35 auto parts() { return _parts.values; } 36 } 37 38 /** 39 * Adds a part to the song. 40 * Params: 41 * part = The part. 42 */ 43 void addPart(SongPart part) 44 { 45 if (!part) 46 { 47 return; 48 } 49 50 _parts[part.title] = part; 51 } 52 53 /** 54 * Gets a part from the song. 55 * Params: 56 * title = The title of the part to get. 57 * Returns: 58 * The part if existing, null otherwise. 59 */ 60 SongPart getPart(SongPartTitle title) 61 { 62 return _parts ? _parts.get(title, null) : null; 63 } 64 65 /// Converts the song to string. Calls toJson(). 66 override string toString() 67 { 68 return toJson(); 69 } 70 71 /// Converts the song to json. 72 string toJson() 73 { 74 auto partsJson = "["; 75 76 if (_parts && _parts.length) 77 { 78 foreach (k,v; _parts) 79 { 80 partsJson ~= v.toJson() ~ ","; 81 } 82 83 partsJson.length -= 1; 84 } 85 86 partsJson ~= "]"; 87 88 return `{"name":"%s","parts": %s}` 89 .format(_name ? _name : "", partsJson); 90 } 91 92 /// Converts the song to xml. 93 string toXml() 94 { 95 auto partsXml = ""; 96 97 if (_parts && _parts.length) 98 { 99 foreach (k,v; _parts) 100 { 101 partsXml ~= v.toXml(); 102 } 103 } 104 105 return `<Song name="%s">%s</Song>` 106 .format(_name, partsXml); 107 } 108 }