1use std::collections::{HashMap, VecDeque};
19
20use crate::braille::equality::equal;
21use crate::defaults::{FloatType, IntegerType};
22use crate::duration::Duration;
23use crate::error::{Error, Result};
24use crate::interval::Interval;
25use crate::makenotation::op_frac;
26use crate::rest::Rest;
27use crate::search::{difflib, iterated, translate_stream_to_string};
28use crate::stream::exact::{Exact, at_offset};
29use crate::stream::{Stream, StreamElement, StreamEvent, StreamKind};
30
31#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
34#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
35pub enum LengthType {
36 Replacement,
38 Elongation,
40 Deletion,
42}
43
44impl LengthType {
45 pub fn as_str(self) -> &'static str {
47 match self {
48 Self::Replacement => "replacement",
49 Self::Elongation => "elongation",
50 Self::Deletion => "deletion",
51 }
52 }
53}
54
55#[derive(Clone, Debug, Default)]
71#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
72pub struct Variant {
73 contents: Stream,
74 groups: Vec<String>,
75 replacement_quarter_length: Option<FloatType>,
76}
77
78impl Variant {
79 pub fn new() -> Self {
81 Self::default()
82 }
83
84 pub fn named(name: impl Into<String>) -> Self {
87 Self {
88 groups: vec![name.into()],
89 ..Self::default()
90 }
91 }
92
93 pub fn from_stream(contents: Stream) -> Self {
95 Self {
96 contents,
97 ..Self::default()
98 }
99 }
100
101 pub fn contents(&self) -> &Stream {
103 &self.contents
104 }
105
106 pub fn contents_mut(&mut self) -> &mut Stream {
108 &mut self.contents
109 }
110
111 pub fn groups(&self) -> &[String] {
114 &self.groups
115 }
116
117 pub fn groups_mut(&mut self) -> &mut Vec<String> {
119 &mut self.groups
120 }
121
122 pub fn replacement_quarter_length(&self) -> FloatType {
126 self.replacement_quarter_length
127 .unwrap_or_else(|| self.contained_highest_time())
128 }
129
130 pub fn set_replacement_quarter_length(&mut self, length: Option<FloatType>) {
133 self.replacement_quarter_length = length;
134 }
135
136 pub fn contained_highest_time(&self) -> FloatType {
139 highest_time(&self.contents)
140 }
141
142 pub fn contained_highest_offset(&self) -> FloatType {
145 self.contents
146 .events()
147 .iter()
148 .map(|event| event.offset())
149 .fold(0.0, FloatType::max)
150 }
151
152 pub fn length_type(&self) -> LengthType {
155 let difference = self.replacement_quarter_length() - self.contained_highest_time();
156 if difference > 0.0 {
157 LengthType::Deletion
158 } else if difference < 0.0 {
159 LengthType::Elongation
160 } else {
161 LengthType::Replacement
162 }
163 }
164
165 pub fn transpose(&self, interval: &Interval) -> Result<Self> {
171 Ok(Self {
172 contents: self.contents.transpose(interval)?,
173 ..self.clone()
174 })
175 }
176}
177
178impl From<Variant> for StreamElement {
179 fn from(variant: Variant) -> Self {
180 StreamElement::Variant(Box::new(variant))
181 }
182}
183
184pub fn highest_time(stream: &Stream) -> FloatType {
188 stream
189 .events()
190 .iter()
191 .map(|event| op_frac(event.offset() + length_of(event.element())))
192 .fold(0.0, FloatType::max)
193}
194
195fn length_of(element: &StreamElement) -> FloatType {
197 match element {
198 StreamElement::Stream(inner) => highest_time(inner),
199 other => other.quarter_length(),
200 }
201}
202
203fn variant_error(message: impl Into<String>) -> Error {
204 Error::Variant(message.into())
205}
206
207fn then(first: Vec<Option<usize>>, next: &[Option<usize>]) -> Vec<Option<usize>> {
209 first
210 .into_iter()
211 .map(|place| place.and_then(|at| next.get(at).copied().flatten()))
212 .collect()
213}
214
215fn unmoved(stream: &Stream) -> Vec<Option<usize>> {
217 (0..stream.leaf_total()).map(Some).collect()
218}
219
220fn is_a(element: &StreamElement, class: &str) -> bool {
222 element.is_instance(class)
223}
224
225fn is_general_note(element: &StreamElement) -> bool {
227 is_a(element, "GeneralNote")
228}
229
230fn is_measure(element: &StreamElement) -> bool {
231 matches!(element, StreamElement::Stream(inner) if inner.kind() == StreamKind::Measure)
232}
233
234fn measure_number(element: &StreamElement) -> Option<IntegerType> {
235 match element {
236 StreamElement::Stream(inner) if inner.kind() == StreamKind::Measure => Some(inner.number()),
237 _ => None,
238 }
239}
240
241fn set_measure_number(element: &mut StreamElement, number: IntegerType) {
242 if let StreamElement::Stream(inner) = element
243 && inner.kind() == StreamKind::Measure
244 {
245 inner.set_number(number);
246 }
247}
248
249fn in_span(
254 offset: FloatType,
255 length: FloatType,
256 start: FloatType,
257 end: Option<FloatType>,
258 include_end: bool,
259) -> bool {
260 let start = op_frac(start);
261 let (end, zero_length_search) = match end {
262 None => (start, true),
263 Some(end) => {
264 let end = op_frac(end);
265 (end, end <= start)
266 }
267 };
268 if offset > end {
269 return false;
270 }
271 if op_frac(offset + length) < start {
272 return false;
273 }
274 if zero_length_search && length == 0.0 {
275 return true;
276 }
277 if offset < start {
278 return false;
279 }
280 !(!include_end && offset == end)
281}
282
283#[derive(Clone, Debug)]
289struct Held {
290 id: usize,
291 origin: Option<usize>,
292 order: usize,
293 offset: FloatType,
294 element: StreamElement,
295}
296
297#[derive(Clone, Debug)]
302struct Site {
303 held: Vec<Held>,
304 next: usize,
305}
306
307impl Site {
308 fn of(stream: &Stream) -> Self {
309 let held: Vec<Held> = stream
310 .events()
311 .iter()
312 .enumerate()
313 .map(|(index, event)| Held {
314 id: index,
315 origin: Some(index),
316 order: index,
317 offset: event.offset(),
318 element: event.element().clone(),
319 })
320 .collect();
321 let next = held.len();
322 let mut site = Self { held, next };
323 site.sort();
324 site
325 }
326
327 fn sort(&mut self) {
328 let grace = |held: &Held| held.element.duration().is_some_and(Duration::is_grace);
329 self.held.sort_by(|left, right| {
330 left.offset
331 .total_cmp(&right.offset)
332 .then(
333 left.element
334 .class_sort_order()
335 .cmp(&right.element.class_sort_order()),
336 )
337 .then(grace(right).cmp(&grace(left)))
338 .then(left.order.cmp(&right.order))
339 });
340 }
341
342 fn get(&self, id: usize) -> Option<&Held> {
343 self.held.iter().find(|held| held.id == id)
344 }
345
346 fn get_mut(&mut self, id: usize) -> Option<&mut Held> {
347 self.held.iter_mut().find(|held| held.id == id)
348 }
349
350 fn offset(&self, id: usize) -> Result<FloatType> {
351 self.get(id)
352 .map(|held| held.offset)
353 .ok_or_else(|| variant_error("the element is not in the stream"))
354 }
355
356 fn variant(&self, id: usize) -> Result<&Variant> {
357 match self.get(id).map(|held| &held.element) {
358 Some(StreamElement::Variant(variant)) => Ok(variant),
359 _ => Err(variant_error("Variant not found in stream")),
360 }
361 }
362
363 fn variant_mut(&mut self, id: usize) -> Result<&mut Variant> {
364 match self.get_mut(id).map(|held| &mut held.element) {
365 Some(StreamElement::Variant(variant)) => Ok(variant),
366 _ => Err(variant_error("Variant not found in stream")),
367 }
368 }
369
370 fn insert(&mut self, offset: FloatType, element: StreamElement) -> usize {
373 let id = self.next;
374 self.next += 1;
375 self.held.push(Held {
376 id,
377 origin: None,
378 order: id,
379 offset: op_frac(offset),
380 element,
381 });
382 self.sort();
383 id
384 }
385
386 fn reinsert(&mut self, mut held: Held, offset: FloatType) {
389 held.offset = op_frac(offset);
390 held.order = self.next;
391 self.next += 1;
392 self.held.push(held);
393 self.sort();
394 }
395
396 fn remove(&mut self, id: usize) -> Option<Held> {
397 let at = self.held.iter().position(|held| held.id == id)?;
398 Some(self.held.remove(at))
399 }
400
401 fn highest_time(&self) -> FloatType {
403 self.held
404 .iter()
405 .map(|held| op_frac(held.offset + length_of(&held.element)))
406 .fold(0.0, FloatType::max)
407 }
408
409 fn in_span(&self, start: FloatType, end: Option<FloatType>, include_end: bool) -> Vec<usize> {
411 self.held
412 .iter()
413 .filter(|held| {
414 in_span(
415 held.offset,
416 length_of(&held.element),
417 start,
418 end,
419 include_end,
420 )
421 })
422 .map(|held| held.id)
423 .collect()
424 }
425
426 fn variants(&self) -> Vec<usize> {
428 self.held
429 .iter()
430 .filter(|held| matches!(held.element, StreamElement::Variant(_)))
431 .map(|held| held.id)
432 .collect()
433 }
434
435 fn measures(&self) -> Vec<usize> {
437 self.held
438 .iter()
439 .filter(|held| is_measure(&held.element))
440 .map(|held| held.id)
441 .collect()
442 }
443
444 fn finish(self, mut base: Stream) -> (Stream, Vec<Option<usize>>) {
448 let events = self
449 .held
450 .into_iter()
451 .map(|held| (StreamEvent::new(held.offset, held.element), held.origin))
452 .collect();
453 let moved = base.replace_events(events);
454 (base, moved)
455 }
456}
457
458fn put(contents: &mut Stream, offset: FloatType, element: StreamElement) {
460 contents.insert_sorted(vec![StreamEvent::new(op_frac(offset), element)]);
461}
462
463fn shift_contents(contents: &mut Stream, shift: FloatType) {
465 let events: Vec<(StreamEvent, Option<usize>)> = contents
466 .events()
467 .iter()
468 .enumerate()
469 .map(|(index, event)| {
470 (
471 StreamEvent::new(op_frac(event.offset() + shift), event.element().clone()),
472 Some(index),
473 )
474 })
475 .collect();
476 contents.replace_events(events);
477}
478
479fn replaced(
485 site: &Site,
486 id: usize,
487 class_list: &[&str],
488 keep_original_offsets: bool,
489 include_spacers: bool,
490) -> Result<Vec<(usize, FloatType)>> {
491 let variant = site.variant(id)?;
492 let start = site.offset(id)?;
493 let spacer = if include_spacers {
494 variant
495 .contents
496 .events()
497 .iter()
498 .find_map(|event| match event.element() {
499 StreamElement::Rest(rest) if rest.hidden() => {
500 Some(rest.duration().quarter_length())
501 }
502 _ => None,
503 })
504 .ok_or_else(|| variant_error("'NoneType' object has no attribute 'duration'"))?
505 } else {
506 0.0
507 };
508 let mut wanted: Vec<&str> = variant
509 .contents
510 .events()
511 .iter()
512 .map(|event| event.element().music21_classes()[0])
513 .collect();
514 wanted.extend_from_slice(class_list);
515 let of_class = |held_id: usize| {
516 site.get(held_id)
517 .is_some_and(|held| wanted.iter().any(|class| is_a(&held.element, class)))
518 };
519 let mut found: Vec<(usize, FloatType)> = Vec::new();
520 match variant.length_type() {
521 LengthType::Replacement | LengthType::Elongation => {
522 let end = start + variant.replacement_quarter_length() + spacer;
523 for held_id in site.in_span(start, Some(end), false) {
524 if of_class(held_id) {
525 found.push((held_id, site.offset(held_id)?));
526 }
527 }
528 }
529 LengthType::Deletion => {
530 let middle = start + variant.contained_highest_time();
531 let end = start + variant.replacement_quarter_length();
532 for held_id in site.in_span(start, Some(middle), false) {
533 if of_class(held_id) {
534 found.push((held_id, site.offset(held_id)?));
535 }
536 }
537 for held_id in site.in_span(middle, Some(end), false) {
538 if found.iter().any(|(seen, _)| *seen == held_id) {
539 return Err(variant_error("the object is already found in this Stream"));
540 }
541 found.push((held_id, op_frac(middle - start + site.offset(held_id)?)));
542 }
543 }
544 }
545 found.retain(|(held_id, _)| *held_id != id);
546 if !keep_original_offsets {
547 for (_, offset) in &mut found {
548 *offset = op_frac(*offset - start);
549 }
550 }
551 let grace = |held_id: usize| {
554 site.get(held_id)
555 .is_some_and(|held| held.element.duration().is_some_and(Duration::is_grace))
556 };
557 let sort_order = |held_id: usize| {
558 site.get(held_id)
559 .map_or(0, |held| held.element.class_sort_order())
560 };
561 found.sort_by(|left, right| {
562 left.1
563 .total_cmp(&right.1)
564 .then(sort_order(left.0).cmp(&sort_order(right.0)))
565 .then(grace(right.0).cmp(&grace(left.0)))
566 });
567 Ok(found)
568}
569
570pub fn replaced_elements(
585 stream: &Stream,
586 variant: usize,
587 class_list: &[&str],
588 keep_original_offsets: bool,
589 include_spacers: bool,
590) -> Result<Stream> {
591 let site = Site::of(stream);
592 let found = replaced(
593 &site,
594 variant,
595 class_list,
596 keep_original_offsets,
597 include_spacers,
598 )?;
599 let mut out = Stream::with_kind(stream.kind());
600 let events: Vec<StreamEvent> = found
601 .into_iter()
602 .filter_map(|(id, offset)| {
603 site.get(id)
604 .map(|held| StreamEvent::new(offset, held.element.clone()))
605 })
606 .collect();
607 out.replace_events(events.into_iter().map(|event| (event, None)).collect());
608 Ok(out)
609}
610
611pub fn remove_replaced_elements_from_stream(
618 stream: &mut Stream,
619 variant: usize,
620 class_list: &[&str],
621) -> Result<()> {
622 let mut site = Site::of(stream);
623 for (id, _) in replaced(&site, variant, class_list, false, false)? {
624 site.remove(id);
625 }
626 let (out, _) = site.finish(stream.clone());
627 *stream = out;
628 Ok(())
629}
630
631fn own_notes(stream: &Stream) -> Vec<crate::search::Searched<'_>> {
635 iterated(stream)
636 .into_iter()
637 .filter(|found| is_general_note(found.element))
638 .collect()
639}
640
641pub fn measure_hashes(stream: &Stream) -> Vec<String> {
644 stream
645 .measures()
646 .into_iter()
647 .map(|measure| translate_stream_to_string(&own_notes(measure)).text)
648 .collect()
649}
650
651fn measure_hash(measure: &Stream) -> String {
652 translate_stream_to_string(&own_notes(measure)).text
653}
654
655fn opcodes_of<'a, T: PartialEq>(a: &'a [T], b: &'a [T]) -> Vec<difflib::Opcode> {
658 let mut seen: Vec<&'a T> = Vec::new();
660 let mut id = |item: &'a T| match seen.iter().position(|known| *known == item) {
661 Some(at) => at,
662 None => {
663 seen.push(item);
664 seen.len() - 1
665 }
666 };
667 let a: Vec<usize> = a.iter().map(&mut id).collect();
668 let b: Vec<usize> = b.iter().map(&mut id).collect();
669 difflib::opcodes(&a, &b)
670}
671
672fn numbered(stream: &Stream, start: IntegerType, end: Option<IntegerType>) -> Vec<usize> {
678 let measures: Vec<(usize, IntegerType)> = stream
679 .events()
680 .iter()
681 .enumerate()
682 .filter_map(|(index, event)| measure_number(event.element()).map(|number| (index, number)))
683 .collect();
684 let numbered = measures.iter().any(|(_, number)| *number != 0);
685 measures
686 .iter()
687 .enumerate()
688 .filter(|(count, (_, number))| {
689 let number = if numbered {
690 *number
691 } else {
692 *count as IntegerType + 1
693 };
694 number >= start && end.is_none_or(|end| number <= end)
695 })
696 .map(|(_, (index, _))| *index)
697 .collect()
698}
699
700fn span_length(stream: &Stream, measures: &[usize]) -> FloatType {
703 let Some(&first) = measures.first() else {
704 return 0.0;
705 };
706 let start = stream.events()[first].offset();
707 measures
708 .iter()
709 .map(|&index| {
710 let event = &stream.events()[index];
711 op_frac(op_frac(event.offset() - start) + length_of(event.element()))
712 })
713 .fold(0.0, FloatType::max)
714}
715
716fn measures_stream(stream: &Stream, measures: &[usize]) -> Stream {
719 let mut out = Stream::new();
720 let Some(&first) = measures.first() else {
721 return out;
722 };
723 let start = stream.events()[first].offset();
724 for &index in measures {
725 let event = &stream.events()[index];
726 put(
727 &mut out,
728 op_frac(event.offset() - start),
729 event.element().clone(),
730 );
731 }
732 out
733}
734
735fn no_such_measure() -> Error {
736 variant_error("'NoneType' object has no attribute 'getOffsetBySite'")
737}
738
739fn made_variant(
743 start_offset: FloatType,
744 contents: Option<&Stream>,
745 variant_name: Option<&str>,
746 variant_groups: Option<&[String]>,
747 replacement_quarter_length: Option<FloatType>,
748) -> Variant {
749 let mut variant = Variant::new();
750 if let Some(groups) = variant_groups {
751 variant.groups = groups.to_vec();
752 }
753 if let Some(name) = variant_name {
754 variant.groups.push(name.to_string());
755 }
756 variant.replacement_quarter_length = replacement_quarter_length;
757 match contents {
758 None => {}
759 Some(stream) if stream.kind() == StreamKind::Measure => {
760 variant
761 .contents
762 .push(StreamElement::Stream(Box::new(stream.clone())));
763 }
764 Some(stream) => {
765 let measures = stream.measures();
766 if measures.is_empty() {
767 for event in stream.events() {
768 put(
769 &mut variant.contents,
770 event.offset() + start_offset,
771 event.element().clone(),
772 );
773 }
774 } else {
775 for measure in measures {
776 variant
777 .contents
778 .push(StreamElement::Stream(Box::new(measure.clone())));
779 }
780 }
781 }
782 }
783 variant
784}
785
786pub fn add_variant(
807 stream: &mut Stream,
808 start_offset: FloatType,
809 contents: Option<&Stream>,
810 variant_name: Option<&str>,
811 variant_groups: Option<&[String]>,
812 replacement_quarter_length: Option<FloatType>,
813) {
814 added(
815 stream,
816 start_offset,
817 contents,
818 variant_name,
819 variant_groups,
820 replacement_quarter_length,
821 );
822}
823
824fn added(
825 stream: &mut Stream,
826 start_offset: FloatType,
827 contents: Option<&Stream>,
828 variant_name: Option<&str>,
829 variant_groups: Option<&[String]>,
830 replacement_quarter_length: Option<FloatType>,
831) -> Vec<Option<usize>> {
832 let variant = made_variant(
833 start_offset,
834 contents,
835 variant_name,
836 variant_groups,
837 replacement_quarter_length,
838 );
839 stream.insert_sorted(vec![StreamEvent::new(
840 start_offset,
841 StreamElement::from(variant),
842 )])
843}
844
845pub fn merge_variants(x: &Stream, y: &Stream, variant_name: &str) -> Result<Stream> {
858 if x.kind() == StreamKind::Score {
859 merge_variant_scores(x, y, variant_name)
860 } else if !x.measures().is_empty() {
861 merge_variant_measure_streams(x, y, variant_name)
862 } else if x
863 .events()
864 .iter()
865 .any(|event| is_general_note(event.element()))
866 && highest_time(x) == highest_time(y)
867 {
868 merge_variants_equal_duration(&[x, y], &[variant_name])
869 } else {
870 Err(variant_error(
871 "Could not determine what merging method to use. Try using a more specific merging function.",
872 ))
873 }
874}
875
876pub fn merge_variant_scores(a: &Stream, v: &Stream, variant_name: &str) -> Result<Stream> {
885 let parts = |score: &Stream| -> Vec<usize> {
886 score
887 .events()
888 .iter()
889 .enumerate()
890 .filter(|(_, event)| {
891 matches!(event.element(), StreamElement::Stream(inner)
892 if matches!(inner.kind(), StreamKind::Part | StreamKind::PartStaff))
893 })
894 .map(|(index, _)| index)
895 .collect()
896 };
897 let (ours, theirs) = (parts(a), parts(v));
898 if ours.len() != theirs.len() {
899 return Err(variant_error(
900 "These scores do not have the same number of parts and cannot be merged.",
901 ));
902 }
903 let mut out = a.clone();
904 for (&part, &other) in ours.iter().zip(&theirs) {
905 let StreamElement::Stream(y) = v.events()[other].element() else {
906 continue;
907 };
908 out.edit_nested(&[part], |stream| {
909 match merge_measure_streams_into(stream, y, variant_name) {
910 Ok(moved) => (Ok(()), moved),
911 Err(error) => (Err(error), unmoved(stream)),
912 }
913 })
914 .0?;
915 }
916 Ok(out)
917}
918
919pub fn merge_variant_measure_streams(x: &Stream, y: &Stream, variant_name: &str) -> Result<Stream> {
933 let mut out = x.clone();
934 merge_measure_streams_into(&mut out, y, variant_name)?;
935 Ok(out)
936}
937
938fn merge_measure_streams_into(
939 out: &mut Stream,
940 y: &Stream,
941 variant_name: &str,
942) -> Result<Vec<Option<usize>>> {
943 let mut moved = unmoved(out);
944 let regions = opcodes_of(&measure_hashes(out), &measure_hashes(y));
945 for region in regions {
946 let (x_start, x_end) = (region.i1 as IntegerType, region.i2 as IntegerType);
947 let (y_start, y_end) = (region.j1 as IntegerType, region.j2 as IntegerType);
948 let start_offset = if region.i1 >= out.measures().len() {
949 highest_time(out)
950 } else {
951 let index = *numbered(out, x_start + 1, Some(x_start + 1))
952 .first()
953 .ok_or_else(no_such_measure)?;
954 out.events()[index].offset()
955 };
956 let (contents, length) = match region.tag {
957 difflib::OpcodeTag::Equal => continue,
958 difflib::OpcodeTag::Replace => (
959 Some(measures_stream(y, &numbered(y, y_start + 1, Some(y_end)))),
960 span_length(out, &numbered(out, x_start + 1, Some(x_end))),
961 ),
962 difflib::OpcodeTag::Delete => (
963 None,
964 span_length(out, &numbered(out, x_start + 1, Some(x_end))),
965 ),
966 difflib::OpcodeTag::Insert => (
967 Some(measures_stream(y, &numbered(y, y_start + 1, Some(y_end)))),
968 0.0,
969 ),
970 };
971 let step = added(
972 out,
973 start_offset,
974 contents.as_ref(),
975 Some(variant_name),
976 None,
977 Some(length),
978 );
979 moved = then(moved, &step);
980 }
981 Ok(moved)
982}
983
984pub fn merge_variants_equal_duration(
994 streams: &[&Stream],
995 variant_names: &[&str],
996) -> Result<Stream> {
997 let Some((first, others)) = streams.split_first() else {
998 return Err(variant_error("list index out of range"));
999 };
1000 let mut out = (*first).clone();
1001 let mut names: Vec<Option<String>> = vec![None];
1002 names.extend(variant_names.iter().map(|name| Some(name.to_string())));
1003 names.resize(streams.len(), None);
1004 let pairs: Vec<(&Stream, Option<String>)> = others
1005 .iter()
1006 .copied()
1007 .zip(names.into_iter().skip(1))
1008 .collect();
1009 equal_duration_into(&mut out, &pairs)?;
1010 Ok(out)
1011}
1012
1013fn equal_duration_into(
1014 out: &mut Stream,
1015 others: &[(&Stream, Option<String>)],
1016) -> Result<Vec<Option<usize>>> {
1017 let mut moved = unmoved(out);
1018 let out_of_range = || variant_error("list index out of range");
1019 for (other, name) in others {
1020 if highest_time(out) != highest_time(other) {
1021 return Err(variant_error("cannot merge streams of different lengths"));
1022 }
1023 let name = name.as_deref();
1024 let part_events: Vec<usize> = out
1025 .events()
1026 .iter()
1027 .enumerate()
1028 .filter(|(_, event)| {
1029 matches!(event.element(), StreamElement::Stream(inner)
1030 if matches!(inner.kind(), StreamKind::Part | StreamKind::PartStaff))
1031 })
1032 .map(|(index, _)| index)
1033 .collect();
1034 let step = if part_events.is_empty() {
1035 let theirs = other.measures();
1036 let ours = numbered_all(out);
1037 if ours.is_empty() {
1038 merged_into(out, &[], other, name)?
1039 } else {
1040 let mut step = unmoved(out);
1041 for (j, &index) in ours.iter().enumerate() {
1042 let measure = theirs.get(j).ok_or_else(out_of_range)?;
1043 step = then(step, &merged_into(out, &[index], measure, name)?);
1044 }
1045 step
1046 }
1047 } else {
1048 let their_parts = other.parts();
1049 let mut step = unmoved(out);
1050 for (i, &part_index) in part_events.iter().enumerate() {
1051 let their_part = their_parts.get(i).ok_or_else(out_of_range)?;
1052 let StreamElement::Stream(part) = out.events()[part_index].element() else {
1053 continue;
1054 };
1055 let ours = numbered_all(part);
1056 if ours.is_empty() {
1057 step = then(step, &merged_into(out, &[part_index], their_part, name)?);
1058 } else {
1059 let theirs = their_part.measures();
1060 for (j, &index) in ours.iter().enumerate() {
1061 let measure = theirs.get(j).ok_or_else(out_of_range)?;
1062 step = then(
1063 step,
1064 &merged_into(out, &[part_index, index], measure, name)?,
1065 );
1066 }
1067 }
1068 }
1069 step
1070 };
1071 moved = then(moved, &step);
1072 }
1073 Ok(moved)
1074}
1075
1076fn numbered_all(stream: &Stream) -> Vec<usize> {
1078 stream
1079 .events()
1080 .iter()
1081 .enumerate()
1082 .filter(|(_, event)| is_measure(event.element()))
1083 .map(|(index, _)| index)
1084 .collect()
1085}
1086
1087fn merged_into(
1089 out: &mut Stream,
1090 path: &[usize],
1091 other: &Stream,
1092 name: Option<&str>,
1093) -> Result<Vec<Option<usize>>> {
1094 let (result, moved) = out.edit_nested(path, |stream| match merge_notes(stream, other, name) {
1095 Ok(moved) => (Ok(()), moved),
1096 Err(error) => (Err(error), unmoved(stream)),
1097 });
1098 result.map(|()| moved)
1099}
1100
1101fn holds_measures_or_parts(stream: &Stream) -> bool {
1102 stream.events().iter().any(|event| {
1103 matches!(event.element(), StreamElement::Stream(inner)
1104 if matches!(inner.kind(), StreamKind::Measure | StreamKind::Part | StreamKind::PartStaff))
1105 })
1106}
1107
1108fn merge_notes(a: &mut Stream, b: &Stream, name: Option<&str>) -> Result<Vec<Option<usize>>> {
1112 if holds_measures_or_parts(a) || holds_measures_or_parts(b) {
1113 return Err(variant_error(
1114 "_mergeVariants cannot merge streams which contain measures or parts.",
1115 ));
1116 }
1117 if highest_time(a) != highest_time(b) {
1118 return Err(variant_error(
1119 "_mergeVariants cannot merge streams which are of different lengths",
1120 ));
1121 }
1122 let notes = |stream: &Stream| -> Vec<StreamEvent> {
1123 stream
1124 .flatten()
1125 .events()
1126 .iter()
1127 .filter(|event| is_general_note(event.element()))
1128 .cloned()
1129 .collect()
1130 };
1131 let (a_notes, b_notes) = (notes(a), notes(b));
1132 let mut moved = unmoved(a);
1133 let (mut i, mut j) = (0, 0);
1134 let mut in_variant = false;
1135 let mut buffer: Vec<&StreamEvent> = Vec::new();
1136 let mut variant_start = 0.0;
1137 let mut insert = |a: &mut Stream, buffer: &[&StreamEvent], start: FloatType| {
1138 let mut variant = Variant::new();
1139 for event in buffer {
1140 put(
1141 &mut variant.contents,
1142 event.offset() - start,
1143 event.element().clone(),
1144 );
1145 }
1146 if let Some(name) = name {
1147 variant.groups.push(name.to_string());
1148 }
1149 let step = a.insert_sorted(vec![StreamEvent::new(start, StreamElement::from(variant))]);
1150 moved = then(std::mem::take(&mut moved), &step);
1151 };
1152 while i < a_notes.len() && j < b_notes.len() {
1153 let (ours, theirs) = (&a_notes[i], &b_notes[j]);
1154 if ours.offset() == theirs.offset() {
1155 if !equal(ours.element(), theirs.element()) {
1156 if !in_variant {
1157 variant_start = theirs.offset();
1158 in_variant = true;
1159 buffer = vec![theirs];
1160 } else {
1161 buffer.push(theirs);
1162 }
1163 } else if in_variant {
1164 insert(a, &buffer, variant_start);
1165 in_variant = false;
1166 buffer.clear();
1167 }
1168 i += 1;
1169 j += 1;
1170 } else if ours.offset() > theirs.offset() {
1171 if !in_variant {
1172 variant_start = theirs.offset();
1173 buffer = vec![theirs];
1174 in_variant = true;
1175 } else {
1176 buffer.push(theirs);
1177 }
1178 j += 1;
1179 } else {
1180 i += 1;
1181 }
1182 }
1183 if in_variant {
1184 insert(a, &buffer, variant_start);
1185 }
1186 Ok(moved)
1187}
1188
1189pub fn merge_part_as_ossia(
1201 main: &Stream,
1202 ossia: &Stream,
1203 ossia_name: &str,
1204 compare_by_measure_number: bool,
1205 recurse_in_measures: bool,
1206) -> Result<Stream> {
1207 let mut out = main.clone();
1208 let no_measure = || variant_error("'NoneType' object has no attribute 'highestTime'");
1209 for event in ossia.events() {
1210 let StreamElement::Stream(measure) = event.element() else {
1211 continue;
1212 };
1213 if measure.kind() != StreamKind::Measure
1214 || !measure
1215 .events()
1216 .iter()
1217 .any(|inner| is_a(inner.element(), "NotRest"))
1218 {
1219 continue;
1220 }
1221 if compare_by_measure_number {
1222 let target = numbered(&out, measure.number(), Some(measure.number()))
1223 .first()
1224 .copied();
1225 if recurse_in_measures {
1226 let index = target.ok_or_else(no_measure)?;
1227 let pairs = [(&**measure, Some(ossia_name.to_string()))];
1228 out.edit_nested(&[index], |stream| {
1229 match equal_duration_into(stream, &pairs) {
1230 Ok(moved) => (Ok(()), moved),
1231 Err(error) => (Err(error), unmoved(stream)),
1232 }
1233 })
1234 .0?;
1235 } else {
1236 let index = target.ok_or_else(no_such_measure)?;
1237 let offset = out.events()[index].offset();
1238 added(
1239 &mut out,
1240 offset,
1241 Some(measure),
1242 Some(ossia_name),
1243 None,
1244 None,
1245 );
1246 }
1247 } else {
1248 let offset = event.offset();
1249 if recurse_in_measures {
1250 let index = out
1251 .events()
1252 .iter()
1253 .enumerate()
1254 .find(|(_, held)| {
1255 is_measure(held.element())
1256 && at_offset(
1257 held.offset(),
1258 length_of(held.element()),
1259 Exact::held(offset),
1260 )
1261 })
1262 .map(|(index, _)| index)
1263 .ok_or_else(no_measure)?;
1264 let pairs = [(&**measure, Some(ossia_name.to_string()))];
1265 out.edit_nested(&[index], |stream| {
1266 match equal_duration_into(stream, &pairs) {
1267 Ok(moved) => (Ok(()), moved),
1268 Err(error) => (Err(error), unmoved(stream)),
1269 }
1270 })
1271 .0?;
1272 } else {
1273 added(
1274 &mut out,
1275 offset,
1276 Some(measure),
1277 Some(ossia_name),
1278 None,
1279 None,
1280 );
1281 }
1282 }
1283 }
1284 Ok(out)
1285}
1286
1287#[allow(clippy::too_many_arguments)]
1293fn best_list(
1294 x: &[&StreamElement],
1295 y: &[&StreamElement],
1296 badness: &mut HashMap<(isize, isize, bool), FloatType>,
1297 lists: &mut HashMap<(isize, isize, bool), Vec<Option<usize>>>,
1298 is_none: bool,
1299 x_index: isize,
1300 y_index: isize,
1301) -> Result<(Vec<Option<usize>>, FloatType)> {
1302 let key = (x_index, y_index, is_none);
1303 if y_index >= y.len() as isize {
1304 lists.insert(key, Vec::new());
1305 badness.insert(key, 0.0);
1306 return Ok((Vec::new(), 0.0));
1307 }
1308 if let Some(&bad) = badness.get(&key) {
1309 return Ok((lists.get(&key).cloned().unwrap_or_default(), bad));
1310 }
1311 let similarity = if x_index == -1 && y_index == -1 {
1312 0.0
1313 } else if is_none {
1314 0.5
1315 } else {
1316 diff_score(x[x_index as usize], y[y_index as usize])?
1317 };
1318 let (mut best_score, mut best_normalized, mut best) = (1.0, 1.0, Vec::new());
1319 let mut consider = |(list, bad): (Vec<Option<usize>>, FloatType)| {
1320 let normalized = if list.is_empty() {
1321 0.0
1322 } else {
1323 bad / list.len() as FloatType
1324 };
1325 if normalized <= best_normalized {
1326 best_score = bad;
1327 best_normalized = normalized;
1328 best = list;
1329 }
1330 };
1331 consider(best_list(x, y, badness, lists, true, x_index, y_index + 1)?);
1332 for k in (x_index + 1)..(x.len() as isize) {
1333 consider(best_list(x, y, badness, lists, false, k, y_index + 1)?);
1334 }
1335 let mut list = best;
1336 if is_none {
1337 list.insert(0, None);
1338 } else if x_index != -1 {
1339 list.insert(0, Some(x_index as usize));
1340 }
1341 let bad = best_score + similarity;
1342 badness.insert(key, bad);
1343 lists.insert(key, list.clone());
1344 Ok((list, bad))
1345}
1346
1347fn diff_score(x: &StreamElement, y: &StreamElement) -> Result<FloatType> {
1350 let (StreamElement::Stream(x), StreamElement::Stream(y)) = (x, y) else {
1351 return Err(variant_error("object has no attribute 'notesAndRests'"));
1352 };
1353 if x.kind() != StreamKind::Measure || y.kind() != StreamKind::Measure {
1354 return Err(variant_error("'Stream' object has no attribute 'number'"));
1355 }
1356 let base = if measure_hash(x) == measure_hash(y) {
1357 0.0
1358 } else {
1359 0.4
1360 };
1361 Ok(base + FloatType::from(x.number() - y.number()) * 0.001)
1362}
1363
1364pub fn refine_variant(stream: &mut Stream, variant: usize) -> Result<()> {
1381 let site = Site::of(stream);
1382 let held = site.variant(variant)?.clone();
1383 let region = replaced(&site, variant, &[], false, false)?;
1384 let region_elements: Vec<&StreamElement> = region
1385 .iter()
1386 .filter_map(|(id, _)| site.get(*id).map(|held| &held.element))
1387 .collect();
1388 let variant_elements: Vec<&StreamElement> = held
1389 .contents
1390 .events()
1391 .iter()
1392 .map(StreamEvent::element)
1393 .collect();
1394 let (chosen, _) = best_list(
1395 ®ion_elements,
1396 &variant_elements,
1397 &mut HashMap::new(),
1398 &mut HashMap::new(),
1399 false,
1400 -1,
1401 -1,
1402 )?;
1403 let ours: Vec<Option<usize>> = (0..region.len()).map(Some).collect();
1404 let mut region_stream = Stream::new();
1407 region_stream.replace_events(
1408 region
1409 .iter()
1410 .filter_map(|(id, offset)| {
1411 site.get(*id)
1412 .map(|held| (StreamEvent::new(*offset, held.element.clone()), None))
1413 })
1414 .collect(),
1415 );
1416 let mut names: Vec<Option<String>> = held.groups.iter().cloned().map(Some).collect();
1417 for step in opcodes_of(&ours, &chosen) {
1418 if region.get(step.i1).is_none() {
1419 return Err(variant_error("index out of range"));
1420 }
1421 if step.tag != difflib::OpcodeTag::Equal {
1422 continue;
1423 }
1424 let ours_matched = numbered(
1425 ®ion_stream,
1426 step.i1 as IntegerType + 1,
1427 Some(step.i2 as IntegerType),
1428 );
1429 let theirs_matched = numbered(
1430 &held.contents,
1431 step.j1 as IntegerType + 1,
1432 Some(step.j2 as IntegerType),
1433 );
1434 names.insert(0, None);
1436 names.resize(2, None);
1437 let name = names[1].clone();
1438 if span_length(®ion_stream, &ours_matched)
1439 != span_length(&held.contents, &theirs_matched)
1440 {
1441 return Err(variant_error("cannot merge streams of different lengths"));
1442 }
1443 if ours_matched.is_empty() {
1444 if !theirs_matched.is_empty() {
1445 return Err(variant_error(
1446 "_mergeVariants cannot merge streams which contain measures or parts.",
1447 ));
1448 }
1449 continue;
1450 }
1451 let theirs: Vec<&Stream> = theirs_matched
1452 .iter()
1453 .filter_map(|&index| held.contents.events()[index].element().as_stream())
1454 .collect();
1455 for (j, &index) in ours_matched.iter().enumerate() {
1456 let measure = theirs
1457 .get(j)
1458 .ok_or_else(|| variant_error("list index out of range"))?;
1459 let id = region[index].0;
1462 let origin = site
1463 .get(id)
1464 .and_then(|held| held.origin)
1465 .ok_or_else(|| variant_error("the measure is not in the stream"))?;
1466 merged_into(stream, &[origin], measure, name.as_deref())?;
1467 }
1468 }
1469 let mut site = Site::of(stream);
1470 site.remove(variant);
1471 let (out, _) = site.finish(stream.clone());
1472 *stream = out;
1473 Ok(())
1474}
1475
1476pub fn make_all_variants_replacements(stream: &Stream, recurse: bool) -> Result<Stream> {
1492 let mut out = stream.clone();
1493 if recurse {
1494 let mut paths: Vec<Vec<usize>> = Vec::new();
1495 collect_stream_paths(&out, &mut Vec::new(), &mut paths);
1496 for path in paths {
1497 out.edit_nested(&path, |inner| match fix_variants(inner) {
1498 Ok(moved) => (Ok(()), moved),
1499 Err(error) => (Err(error), unmoved(inner)),
1500 })
1501 .0?;
1502 }
1503 } else {
1504 fix_variants(&mut out)?;
1505 }
1506 Ok(out)
1507}
1508
1509fn collect_stream_paths(stream: &Stream, path: &mut Vec<usize>, out: &mut Vec<Vec<usize>>) {
1512 for (index, event) in stream.events().iter().enumerate() {
1513 if let StreamElement::Stream(inner) = event.element() {
1514 path.push(index);
1515 out.push(path.clone());
1516 collect_stream_paths(inner, path, out);
1517 path.pop();
1518 }
1519 }
1520}
1521
1522fn first_of_kinds<'a>(
1525 elements: impl IntoIterator<Item = &'a StreamElement>,
1526) -> Option<&'static str> {
1527 elements
1528 .into_iter()
1529 .find(|element| {
1530 ["Measure", "Note", "Rest"]
1531 .iter()
1532 .any(|class| is_a(element, class))
1533 })
1534 .map(|element| element.music21_classes()[0])
1535}
1536
1537fn fix_variants(stream: &mut Stream) -> Result<Vec<Option<usize>>> {
1539 #[derive(PartialEq)]
1540 enum Kind {
1541 Insertion,
1542 Deletion,
1543 }
1544 let mut site = Site::of(stream);
1545 for id in site.variants() {
1546 let variant = site.variant(id)?;
1547 let length = variant.replacement_quarter_length();
1548 let kind = match variant.length_type() {
1549 LengthType::Elongation if length == 0.0 => Kind::Insertion,
1550 LengthType::Deletion if variant.contained_highest_time() == 0.0 => Kind::Deletion,
1551 _ => continue,
1552 };
1553 let offset = site.offset(id)?;
1554 let initial = offset == 0.0;
1555 let last = !initial && offset + length == site.highest_time();
1556 let target_length;
1557 if (kind == Kind::Insertion && initial) || (kind == Kind::Deletion && !last) {
1558 let target = next_element(&site, id)?;
1559 let Some(target) = target else {
1560 return Err(variant_error("cannot append None to a Stream"));
1561 };
1562 let held = site
1563 .get_mut(target)
1564 .ok_or_else(|| variant_error("the element is not in the stream"))?;
1565 if let StreamElement::Stream(inner) = &mut held.element {
1566 let kept: Vec<(StreamEvent, Option<usize>)> = inner
1567 .events()
1568 .iter()
1569 .enumerate()
1570 .filter(|(_, event)| {
1571 !matches!(
1572 event.element(),
1573 StreamElement::Clef(_) | StreamElement::TimeSignature(_)
1574 )
1575 })
1576 .map(|(index, event)| (event.clone(), Some(index)))
1577 .collect();
1578 inner.replace_events(kept);
1579 }
1580 let copy = held.element.clone();
1581 target_length = copy.quarter_length();
1582 site.variant_mut(id)?.contents.push(copy);
1583 } else {
1584 let target = previous_element(&site, id)?.ok_or_else(|| {
1585 variant_error("'NoneType' object has no attribute 'getOffsetBySite'")
1586 })?;
1587 let held = site
1588 .get(target)
1589 .ok_or_else(|| variant_error("the element is not in the stream"))?
1590 .clone();
1591 target_length = held.element.quarter_length();
1592 let variant = site.variant_mut(id)?;
1593 shift_contents(&mut variant.contents, target_length);
1594 put(&mut variant.contents, 0.0, held.element.clone());
1595 let moving = site
1596 .remove(id)
1597 .ok_or_else(|| variant_error("Variant not found in stream"))?;
1598 site.reinsert(moving, held.offset);
1599 }
1600 let variant = site.variant_mut(id)?;
1601 let old = variant.replacement_quarter_length();
1602 variant.replacement_quarter_length = Some(op_frac(old + target_length));
1603 }
1604 let (out, moved) = site.finish(stream.clone());
1605 *stream = out;
1606 Ok(moved)
1607}
1608
1609fn next_element(site: &Site, id: usize) -> Result<Option<usize>> {
1613 let found = replaced(site, id, &[], false, false)?;
1614 let variant = site.variant(id)?;
1615 let offset = site.offset(id)?;
1616 let (class, start) = if variant.length_type() == LengthType::Elongation {
1617 (
1618 first_of_kinds(variant.contents.events().iter().map(StreamEvent::element)),
1619 offset,
1620 )
1621 } else {
1622 (
1623 first_of_kinds(
1624 found
1625 .iter()
1626 .filter_map(|(found_id, _)| site.get(*found_id).map(|held| &held.element)),
1627 ),
1628 offset + variant.replacement_quarter_length(),
1629 )
1630 };
1631 let Some(class) = class else {
1632 return Ok(None);
1633 };
1634 Ok(site
1635 .in_span(start, Some(site.highest_time()), true)
1636 .into_iter()
1637 .find(|candidate| {
1638 site.get(*candidate)
1639 .is_some_and(|held| is_a(&held.element, class))
1640 }))
1641}
1642
1643fn previous_element(site: &Site, id: usize) -> Result<Option<usize>> {
1646 let found = replaced(site, id, &[], false, false)?;
1647 let variant = site.variant(id)?;
1648 let class = if variant.length_type() == LengthType::Elongation {
1649 first_of_kinds(variant.contents.events().iter().map(StreamEvent::element))
1650 } else {
1651 first_of_kinds(
1652 found
1653 .iter()
1654 .filter_map(|(found_id, _)| site.get(*found_id).map(|held| &held.element)),
1655 )
1656 };
1657 let class = class
1658 .ok_or_else(|| variant_error("Cannot find any Measures, Notes, or Rests in variant"))?;
1659 let offset = site.offset(id)?;
1660 Ok(site
1661 .in_span(0.0, Some(offset), false)
1662 .into_iter()
1663 .rfind(|candidate| {
1664 site.get(*candidate)
1665 .is_some_and(|held| is_a(&held.element, class))
1666 }))
1667}
1668
1669pub fn make_variant_blocks(stream: &mut Stream) -> Result<()> {
1680 let mut site = Site::of(stream);
1681 let mut failed = None;
1682 'variants: for id in site.variants() {
1683 let start = site.offset(id)?;
1684 let end = site.variant(id)?.replacement_quarter_length() + start;
1685 let conflicting: Vec<usize> = site
1686 .in_span(start, Some(end), false)
1687 .into_iter()
1688 .filter(|other| {
1689 matches!(
1690 site.get(*other).map(|held| &held.element),
1691 Some(StreamElement::Variant(_))
1692 )
1693 })
1694 .collect();
1695 for other in conflicting {
1696 let other_start = site.offset(other)?;
1697 if other_start == start {
1698 continue;
1699 }
1700 let shift = op_frac(other_start - start);
1701 let variant = site.variant_mut(other)?;
1702 let old = variant.replacement_quarter_length();
1703 shift_contents(&mut variant.contents, shift);
1704 let mut rest = Rest::new(Duration::new(shift)?);
1705 rest.set_hidden(true);
1706 put(&mut variant.contents, 0.0, StreamElement::Rest(rest));
1707 variant.replacement_quarter_length = Some(old);
1708 let moving = site
1709 .remove(other)
1710 .ok_or_else(|| variant_error("Variant not found in stream"))?;
1711 site.reinsert(moving, start);
1712 failed = Some(variant_error(
1713 "'StreamIterator' object has no attribute 'append'",
1714 ));
1715 break 'variants;
1716 }
1717 }
1718 let (out, _) = site.finish(stream.clone());
1719 *stream = out;
1720 failed.map_or(Ok(()), Err)
1721}
1722
1723enum Renumber {
1727 Deleted(IntegerType),
1729 Inserted(Option<IntegerType>, Vec<usize>),
1731}
1732
1733impl Renumber {
1734 fn key(&self) -> IntegerType {
1735 match self {
1736 Self::Deleted(number) => *number,
1737 Self::Inserted(prior, _) => prior.unwrap_or(-9999),
1738 }
1739 }
1740}
1741
1742fn activate_replacement(site: &mut Site, id: usize, match_by_span: bool) -> Result<()> {
1745 let variant = site.variant(id)?.clone();
1746 let start = site.offset(id)?;
1747 let mut removed = Variant::named("default");
1748 if !match_by_span {
1749 let mut matched = 0;
1750 for event in variant.contents.events() {
1751 let exact = Exact::held(start).plus(Exact::held(event.offset()));
1754 let at = exact.to_float();
1755 let class = event.element().music21_classes()[0];
1756 let target = site.held.iter().find(|held| {
1757 is_a(&held.element, class)
1758 && at_offset(held.offset, length_of(&held.element), exact)
1759 });
1760 let target = target.map(|held| held.id);
1761 if let Some(target) = target {
1762 matched += 1;
1763 let taken = site
1764 .remove(target)
1765 .ok_or_else(|| variant_error("the element is not in the stream"))?;
1766 let mut element = event.element().clone();
1767 if let Some(number) = measure_number(&taken.element) {
1768 set_measure_number(&mut element, number);
1769 }
1770 removed.contents.push(taken.element);
1771 site.insert(at, element);
1772 }
1773 }
1774 if matched > 0 {
1775 site.remove(id);
1776 site.insert(start, removed.into());
1777 }
1778 return Ok(());
1779 }
1780 let mut deleted = VecDeque::new();
1781 for (target, _) in replaced(site, id, &[], false, false)? {
1782 let at = op_frac(site.offset(target)? - start);
1783 let taken = site
1784 .remove(target)
1785 .ok_or_else(|| variant_error("the element is not in the stream"))?;
1786 if let Some(number) = measure_number(&taken.element) {
1787 deleted.push_back(number);
1788 }
1789 put(&mut removed.contents, at, taken.element);
1790 }
1791 for event in variant.contents.events() {
1792 let mut element = event.element().clone();
1793 if is_measure(&element) {
1794 set_measure_number(&mut element, deleted.pop_front().unwrap_or(0));
1795 }
1796 site.insert(start + event.offset(), element);
1797 }
1798 site.remove(id);
1799 site.insert(start, removed.into());
1800 Ok(())
1801}
1802
1803fn activate_changed_length(
1809 site: &mut Site,
1810 id: usize,
1811 insertion: bool,
1812) -> Result<(Vec<IntegerType>, Renumber)> {
1813 let variant = site.variant(id)?.clone();
1814 let start = site.offset(id)?;
1815 let mut removed = Variant::named("default");
1816 removed.replacement_quarter_length = Some(variant.contained_highest_time());
1817 let mut deleted = VecDeque::new();
1818 for (target, _) in replaced(site, id, &[], false, false)? {
1819 let at = op_frac(site.offset(target)? - start);
1820 let taken = site
1821 .remove(target)
1822 .ok_or_else(|| variant_error("the element is not in the stream"))?;
1823 if let Some(number) = measure_number(&taken.element) {
1824 deleted.push_back(number);
1825 }
1826 put(&mut removed.contents, at, taken.element);
1827 }
1828 let mut highest = None;
1829 let mut inserted = Vec::new();
1830 for event in variant.contents.events() {
1831 let mut element = event.element().clone();
1832 let mut new_measure = false;
1833 if is_measure(&element) {
1834 match deleted.pop_front() {
1835 Some(number) => {
1836 set_measure_number(&mut element, number);
1837 highest = Some(number);
1838 }
1839 None => {
1840 set_measure_number(&mut element, 0);
1841 new_measure = true;
1842 }
1843 }
1844 }
1845 let new_id = site.insert(start + event.offset(), element);
1846 if new_measure {
1847 inserted.push(new_id);
1848 }
1849 }
1850 if insertion && highest.is_none() {
1851 let mut most = 0;
1852 for measure in site.in_span(0.0, Some(site.offset(id)?), true) {
1853 if let Some(number) = site
1854 .get(measure)
1855 .and_then(|held| measure_number(&held.element))
1856 && number > most
1857 {
1858 most = number;
1859 }
1860 }
1861 highest = Some(most);
1862 }
1863 site.remove(id);
1864 site.insert(start, removed.into());
1865 Ok((
1866 deleted.into_iter().collect(),
1867 Renumber::Inserted(highest, inserted),
1868 ))
1869}
1870
1871struct Opening<'a> {
1874 shift: FloatType,
1875 end: FloatType,
1876 include_end: bool,
1877 exempt: &'a Vec<usize>,
1878 exempt_shift: FloatType,
1879}
1880
1881fn shift_gaps(site: &mut Site, gaps: &[(FloatType, FloatType, Vec<usize>)], remove: bool) {
1885 let duration = site.highest_time();
1886 let mut sorted: Vec<&(FloatType, FloatType, Vec<usize>)> = gaps.iter().collect();
1887 sorted.sort_by(|left, right| left.0.total_cmp(&right.0));
1888 let bounds = |i: usize| -> (FloatType, bool) {
1889 match sorted.get(i + 1) {
1890 Some(next) => (next.0, false),
1891 None => (duration, true),
1892 }
1893 };
1894 if remove {
1895 let mut shift = 0.0;
1896 for (i, (start, amount, exempt)) in sorted.iter().enumerate() {
1897 let (end, include_end) = bounds(i);
1898 shift += amount;
1899 for id in site.in_span(start + amount, Some(end), include_end) {
1900 if exempt.contains(&id) {
1901 continue;
1902 }
1903 if let Some(held) = site.get_mut(id) {
1904 held.offset = op_frac(held.offset - shift);
1905 }
1906 }
1907 }
1908 } else {
1909 let mut shift = 0.0;
1910 let mut shifts: Vec<(FloatType, Opening<'_>)> = Vec::new();
1912 for (i, (start, amount, exempt)) in sorted.iter().enumerate() {
1913 let (end, include_end) = bounds(i);
1914 let exempt_shift = shift;
1915 shift += amount;
1916 let entry = Opening {
1917 shift,
1918 end,
1919 include_end,
1920 exempt,
1921 exempt_shift,
1922 };
1923 match shifts.iter_mut().find(|(known, _)| known == start) {
1924 Some((_, held)) => *held = entry,
1925 None => shifts.push((*start, entry)),
1926 }
1927 }
1928 shifts.sort_by(|left, right| right.0.total_cmp(&left.0));
1929 for (offset, opening) in shifts {
1930 for id in site.in_span(offset, Some(opening.end), opening.include_end) {
1931 let by = if opening.exempt.contains(&id) {
1932 opening.exempt_shift
1933 } else {
1934 opening.shift
1935 };
1936 if let Some(held) = site.get_mut(id) {
1937 held.offset = op_frac(held.offset + by);
1938 }
1939 }
1940 }
1941 }
1942 site.sort();
1943}
1944
1945fn fix_measure_numbers(site: &mut Site, mut all: Vec<Renumber>) -> Result<()> {
1947 if all.is_empty() {
1948 return Ok(());
1949 }
1950 all.sort_by_key(Renumber::key);
1951 let mut old_measures = site.measures();
1952 let mut new_measures: Vec<usize> = Vec::new();
1953 let mut cumulative: IntegerType = 0;
1954 let mut old_corrections: Vec<(IntegerType, IntegerType)> = Vec::new();
1955 let mut new_corrections: Vec<(IntegerType, IntegerType)> = Vec::new();
1956 let correct =
1957 |corrections: &mut Vec<(IntegerType, IntegerType)>, at: IntegerType, by: IntegerType| {
1958 match corrections.iter_mut().find(|(known, _)| *known == at) {
1959 Some((_, held)) => *held = by,
1960 None => corrections.push((at, by)),
1961 }
1962 };
1963 for entry in all {
1964 match entry {
1965 Renumber::Inserted(prior, measures) => {
1966 if measures.is_empty() {
1967 continue;
1968 }
1969 let prior = prior.ok_or_else(|| {
1970 variant_error("unsupported operand type(s) for +: 'NoneType' and 'int'")
1971 })?;
1972 cumulative += measures.len() as IntegerType;
1973 let mut next = prior + 1;
1974 for id in measures {
1975 old_measures.retain(|known| *known != id);
1977 new_measures.push(id);
1978 if let Some(held) = site.get_mut(id) {
1979 set_measure_number(&mut held.element, next);
1980 }
1981 next += 1;
1982 }
1983 correct(&mut old_corrections, prior + 1, cumulative);
1984 correct(&mut new_corrections, next, cumulative);
1985 }
1986 Renumber::Deleted(number) => {
1987 cumulative -= 1;
1988 correct(&mut old_corrections, number + 1, cumulative);
1989 correct(&mut new_corrections, number + 1, cumulative);
1990 }
1991 }
1992 }
1993 for (measures, corrections) in [
1994 (old_measures, old_corrections),
1995 (new_measures, new_corrections),
1996 ] {
1997 let mut corrections = corrections;
1998 corrections.sort_by_key(|(at, _)| -*at);
1999 let mut previous: Option<IntegerType> = None;
2000 for (at, shift) in corrections {
2001 for &id in &measures {
2002 let Some(held) = site.get_mut(id) else {
2003 continue;
2004 };
2005 let Some(number) = measure_number(&held.element) else {
2006 continue;
2007 };
2008 if previous.is_none_or(|boundary| number < boundary) && number >= at {
2009 set_measure_number(&mut held.element, number + shift);
2010 }
2011 }
2012 previous = Some(at);
2013 }
2014 }
2015 Ok(())
2016}
2017
2018impl Stream {
2019 pub fn activate_variants(&self, group: Option<&str>, match_by_span: bool) -> Result<Stream> {
2044 let mut site = Site::of(self);
2045 let (mut elongations, mut deletions) = (Vec::new(), Vec::new());
2046 for id in site.variants() {
2047 let variant = site.variant(id)?;
2048 if group.is_some_and(|group| !variant.groups.iter().any(|known| known == group)) {
2049 continue;
2050 }
2051 match variant.length_type() {
2052 LengthType::Elongation => elongations.push(id),
2053 LengthType::Deletion => deletions.push(id),
2054 LengthType::Replacement => activate_replacement(&mut site, id, match_by_span)?,
2055 }
2056 }
2057 let mut deleted: Vec<Renumber> = Vec::new();
2058 let mut inserted: Vec<Renumber> = Vec::new();
2059 let mut gaps = Vec::new();
2060 for id in deletions {
2061 let variant = site.variant(id)?;
2062 let difference =
2063 variant.replacement_quarter_length() - variant.contained_highest_time();
2064 let start = site.offset(id)? + variant.contained_highest_time();
2065 let (left, renumber) = activate_changed_length(&mut site, id, false)?;
2066 gaps.push((start, difference, Vec::new()));
2067 deleted.extend(left.into_iter().map(Renumber::Deleted));
2068 inserted.push(renumber);
2069 }
2070 shift_gaps(&mut site, &gaps, true);
2071 let mut openings = Vec::new();
2072 for &id in &elongations {
2073 let variant = site.variant(id)?;
2074 let difference =
2075 variant.replacement_quarter_length() - variant.contained_highest_time();
2076 let start = site.offset(id)? + variant.replacement_quarter_length();
2077 openings.push((start, -difference, vec![id]));
2078 }
2079 shift_gaps(&mut site, &openings, false);
2080 for id in elongations {
2081 let (left, renumber) = activate_changed_length(&mut site, id, true)?;
2082 inserted.push(renumber);
2083 deleted.extend(left.into_iter().map(Renumber::Deleted));
2084 }
2085 deleted.extend(inserted);
2086 fix_measure_numbers(&mut site, deleted)?;
2087 Ok(site.finish(self.clone()).0)
2088 }
2089
2090 pub fn show_variant_as_ossialike_part(
2100 &self,
2101 part: usize,
2102 variant_groups: &[&str],
2103 ) -> Result<Stream> {
2104 let mut out = self.clone();
2105 let source = self
2106 .parts()
2107 .get(part)
2108 .map(|found| (*found).clone())
2109 .ok_or_else(|| variant_error("Could not find the part in the score"))?;
2110 for group in variant_groups {
2111 let mut expressed = false;
2112 let mut held: Vec<(usize, StreamEvent, Option<usize>)> = Vec::new();
2115 let mut later = source.events().len();
2116 for (index, event) in source.events().iter().enumerate() {
2117 match event.element() {
2118 StreamElement::Variant(variant) => {
2119 if !variant.groups.iter().any(|known| known == group)
2120 || matches!(
2121 variant.length_type(),
2122 LengthType::Elongation | LengthType::Deletion
2123 )
2124 {
2125 continue;
2126 }
2127 expressed = true;
2128 held.push((index, event.clone(), Some(index)));
2129 }
2130 element if is_general_note(element) => {
2131 let mut rest = Rest::new(Duration::new(element.quarter_length())?);
2132 rest.set_hidden(true);
2133 held.push((
2134 later,
2135 StreamEvent::new(event.offset(), StreamElement::Rest(rest)),
2136 None,
2137 ));
2138 later += 1;
2139 }
2140 StreamElement::Stream(measure) if measure.kind() == StreamKind::Measure => {
2141 let length = highest_time(measure);
2142 let mut emptied = (**measure).clone();
2143 let kept: Vec<(StreamEvent, Option<usize>)> = emptied
2144 .events()
2145 .iter()
2146 .enumerate()
2147 .filter(|(_, inner)| !is_general_note(inner.element()))
2148 .map(|(at, inner)| (inner.clone(), Some(at)))
2149 .collect();
2150 emptied.replace_events(kept);
2151 let mut rest = Rest::new(Duration::new(length)?);
2152 rest.set_hidden(true);
2153 put(&mut emptied, 0.0, StreamElement::Rest(rest));
2154 held.push((
2155 index,
2156 StreamEvent::new(
2157 event.offset(),
2158 StreamElement::Stream(Box::new(emptied)),
2159 ),
2160 Some(index),
2161 ));
2162 }
2163 _ => held.push((index, event.clone(), Some(index))),
2164 }
2165 }
2166 held.sort_by(|left, right| {
2167 crate::makenotation::event_order(&left.1, &right.1).then(left.0.cmp(&right.0))
2168 });
2169 let mut new_part = source.clone();
2170 new_part.replace_events(
2171 held.into_iter()
2172 .map(|(_, event, origin)| (event, origin))
2173 .collect(),
2174 );
2175 let new_part = new_part.activate_variants(Some(group), true)?;
2176 if expressed {
2177 out.insert_sorted(vec![StreamEvent::new(
2178 0.0,
2179 StreamElement::Stream(Box::new(new_part)),
2180 )]);
2181 }
2182 }
2183 Ok(out)
2184 }
2185}