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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
//! # Overview
//!
//! `musicxml` is a library for reading and writing MusicXML files in Rust. MusicXML is a standard format for
//! representing Western musical notation and is widely used in music notation software such as Finale, Sibelius,
//! and MuseScore. This library provides a simple interface for parsing MusicXML files and converting them into
//! a structured data format that can be easily manipulated and analyzed programmatically.
//!
//! The library is designed to be easy to use and flexible, allowing you to read and write MusicXML files with
//! minimal effort. It provides functions for reading MusicXML files and converting them into a structured
//! data format, as well as functions for writing structured data back to MusicXML files. It is also designed to
//! be robust and reliable, handling a wide variety of MusicXML files and formats with ease.
//!
//! # Installation
//!
//! To use the `musicxml` library in your Rust project, simply add the following line to your `Cargo.toml` file:
//!
//! ```toml
//! [dependencies]
//! musicxml = "1.1"
//! ```
//!
//! # Parsing MusicXML Files
//!
//! The recommended way to parse a MusicXML file is to use the [read_score_partwise] and [read_score_timewise] functions.
//! The difference between these two functions is based on the internal representation of the MusicXML data that you would
//! like to work with. The [read_score_partwise] function returns a [ScorePartwise] object, which is a representation in
//! which the score is divided into "parts," typically corresponding to either individual musical instruments or even
//! individual hands in multi-hand instruments. The [read_score_timewise] function returns a [ScoreTimewise] object,
//! in which the representation is divided into "measures" instead of "parts."
//!
//! The data encoded in either of these representations is identical, but the way in which the data is structured is different.
//! The primary difference is that in the [ScorePartwise] representation, the top-level data structure is a list of parts,
//! each of which contain a list of measures containing the actual notes to be played by the enclosing part. In the
//! [ScoreTimewise] representation, the top-level data structure is a list of measures, each of which contain a list of parts
//! indicating what each part is supposed to play in the enclosing measure.
//!
//! Transitioning between these two representations is handled internally and transparently to the user, meaning that
//! regardless of how the original MusicXML file was encoded, you can parse the data using whichever representation you prefer,
//! simply by calling the appropriate function. To read a MusicXML file and get a [ScorePartwise] object, simply do the
//! following:
//!
//! ```no_run
//! use musicxml::read_score_partwise;
//!
//! match read_score_partwise("path/to/file.musicxml") {
//! Ok(score) => {}, // Do something with the score
//! Err(e) => println!("Error reading MusicXML file: {}", e),
//! }
//! ```
//!
//! Likewise, to read a MusicXML file and get a [ScoreTimewise] object, you can do the following:
//!
//! ```no_run
//! use musicxml::read_score_timewise;
//!
//! match read_score_timewise("path/to/file.musicxml") {
//! Ok(score) => {}, // Do something with the score
//! Err(e) => println!("Error reading MusicXML file: {}", e),
//! }
//! ```
//!
//! Note that this library is able to read both `.musicxml` files and compressed `.mxl` files. The file type being read is
//! determined internally, and decoding will be handled automatically when calling either of the above functions.
//!
//! If you are using this library in a `no_std` environment, you can parse MusicXML data directly by calling the
//! [read_score_data_partwise] and [read_score_data_timewise] functions. These functions take a `Vec<u8>` containing
//! raw MusicXML data and return a [ScorePartwise] or [ScoreTimewise] object, respectively.
//!
//! # Writing MusicXML Files
//!
//! Assuming you have a [ScorePartwise] or [ScoreTimewise] object that you would like to write to a MusicXML file, you can
//! use the [write_partwise_score] and [write_timewise_score] functions to do so. The difference between these two functions
//! is similar to the difference between the [read_score_partwise] and [read_score_timewise] functions, in that the former
//! writes a [ScorePartwise] object to a file, while the latter writes a [ScoreTimewise] object.
//!
//! As with reading MusicXML files, the representation in which you would like to store the output file can be specified as
//! a parameter to either of these functions to allow you to explicitly convert from your original representation to the
//! alternate representation when storing. Additionally, a `compressed` parameter exists to indicate whether the output file
//! should be compressed as an `.mxl` file or stored as a plain `.musicxml` file.
//!
//! To write a [ScorePartwise] object to a standard MusicXML file in its default representation, you can do the following:
//!
//! ```ignore
//! use musicxml::write_partwise_score;
//!
//! // Assume ScorePartwise "score" object created elsewhere
//! match write_partwise_score("path/to/output.musicxml", &score, false, false) {
//! Ok(_) => println!("Successfully wrote MusicXML file"),
//! Err(e) => println!("Error writing MusicXML file: {}", e),
//! }
//! ```
//!
//! Alternately, to write a [ScoreTimewise] object to a compressed MusicXML file using a partwise representation,
//! you can do the following:
//!
//! ```ignore
//! use musicxml::write_timewise_score;
//!
//! // Assume ScoreTimewise "score" object created elsewhere
//! match write_timewise_score("path/to/output.musicxml", &score, true, true) {
//! Ok(_) => println!("Successfully wrote compressed MusicXML file"),
//! Err(e) => println!("Error writing compressed MusicXML file: {}", e),
//! }
//! ```
//!
//! As with reading data, if you are using this library in a `no_std` environment, you can write MusicXML data
//! directly to a data buffer by calling the [write_partwise_score_data] and [write_timewise_score_data] functions.
extern crate alloc;
use ;
/// Contains the main data types used by the MusicXML format.
///
/// Note that these data types correspond to the textual contents of an XML tag. For example, the XML string
/// `<element>123</element>` might specify that the `123` value be of data type `UnsignedInteger`.
/// This module defines all the various data types that a MusicXML text field can have.
/// Contains the main elements used in the MusicXML format.
///
/// Note that these elements correspond to the XML tags themselves and are usually containers for other
/// MusicXML elements or data types. For example, take the following contrived MusicXML string:
///
/// ```xml
/// <note>
/// <color>#FF0000</color>
/// <type>quarter</type>
/// <duration>1</duration>
/// </note>
/// ```
///
/// The `note` element is a container for the `color`, `type`, and `duration` elements, which in turn contain
/// data types such as `Color`, `NoteType`, and `PositiveInteger`, respectively.
///
/// This module defines all the various container elements that a MusicXML file can have.
/// Contains functions for parsing and writing MusicXML files.
///
/// It is recommended that the top-level [MusicXML][crate] functions be used to read and write MusicXML files;
/// however, the functions in this module can be used directly for more fine-grained control over the parsing
/// and writing process.
use ;
/// Reads a MusicXML file and returns a [ScorePartwise] object.
///
/// The specified file can be either a `.musicxml` file or a compressed `.mxl` file.
///
/// # Errors
///
/// If the file does not exist, cannot be read, or is not a valid MusicXML file, an
/// error message will be returned.
/// Reads a MusicXML file and returns a [ScoreTimewise] object.
///
/// The specified file can be either a `.musicxml` file or a compressed `.mxl` file.
///
/// # Errors
///
/// If the file does not exist, cannot be read, or is not a valid MusicXML file, an
/// error message will be returned.
/// Reads MusicXML data and returns a [ScorePartwise] object.
///
/// The specified data should have been read directly from either a `.musicxml` file or a compressed `.mxl` file.
///
/// # Errors
///
/// If the data cannot be parsed or does not represent valid MusicXML contents, an error message will be returned.
/// Reads MusicXML data and returns a [ScoreTimewise] object.
///
/// The specified data should have been read directly from either a `.musicxml` file or a compressed `.mxl` file.
///
/// # Errors
///
/// If the data cannot be parsed or does not represent valid MusicXML contents, an error message will be returned.
/// Writes a [ScorePartwise] object into a MusicXML file.
///
/// If the `compressed` parameter is set to `true`, the MusicXML file will be written as a compressed `.mxl` file.
/// If the `write_as_timewise` parameter is set to `true`, the MusicXML file will be converted into a timewise
/// format and written as a `<score-timewise>` element.
///
/// # Errors
///
/// If the file cannot be written or the data cannot be serialized into a valid MusicXML format, an error message
/// will be returned.
/// Writes a [ScoreTimewise] object into a MusicXML file.
///
/// If the `compressed` parameter is set to `true`, the MusicXML file will be written as a compressed `.mxl` file.
/// If the `write_as_partwise` parameter is set to `true`, the MusicXML file will be converted into a partwise
/// format and written as a `<score-partwise>` element.
///
/// # Errors
///
/// If the file cannot be written or the data cannot be serialized into a valid MusicXML format, an error message
/// will be returned.
/// Writes a [ScorePartwise] object into a MusicXML data buffer.
///
/// If the `compressed` parameter is set to `true`, the MusicXML contents will be written as compressed `.mxl` data.
/// If the `write_as_timewise` parameter is set to `true`, the MusicXML contents will be converted into a timewise
/// format and written as a `<score-timewise>` element.
///
/// # Errors
///
/// If the data cannot be serialized into a valid MusicXML format, an error message will be returned.
/// Writes a [ScoreTimewise] object into a MusicXML data buffer.
///
/// If the `compressed` parameter is set to `true`, the MusicXML contents will be written as compressed `.mxl` data.
/// If the `write_as_partwise` parameter is set to `true`, the MusicXML contents will be converted into a partwise
/// format and written as a `<score-partwise>` element.
///
/// # Errors
///
/// If the data cannot be serialized into a valid MusicXML format, an error message will be returned.