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("the variant has no hidden rest to space it"))?
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("no measure there to place the variant at")
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("no streams to merge"));
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("a version has fewer parts or measures than the first");
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("no measure there to merge the ossia into");
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("only streams can be compared"));
1352 };
1353 if x.kind() != StreamKind::Measure || y.kind() != StreamKind::Measure {
1354 return Err(variant_error("only measures can be compared"));
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("fewer measures matched than to align"))?;
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)?
1585 .ok_or_else(|| variant_error("no element before the variant to place it after"))?;
1586 let held = site
1587 .get(target)
1588 .ok_or_else(|| variant_error("the element is not in the stream"))?
1589 .clone();
1590 target_length = held.element.quarter_length();
1591 let variant = site.variant_mut(id)?;
1592 shift_contents(&mut variant.contents, target_length);
1593 put(&mut variant.contents, 0.0, held.element.clone());
1594 let moving = site
1595 .remove(id)
1596 .ok_or_else(|| variant_error("Variant not found in stream"))?;
1597 site.reinsert(moving, held.offset);
1598 }
1599 let variant = site.variant_mut(id)?;
1600 let old = variant.replacement_quarter_length();
1601 variant.replacement_quarter_length = Some(op_frac(old + target_length));
1602 }
1603 let (out, moved) = site.finish(stream.clone());
1604 *stream = out;
1605 Ok(moved)
1606}
1607
1608fn next_element(site: &Site, id: usize) -> Result<Option<usize>> {
1612 let found = replaced(site, id, &[], false, false)?;
1613 let variant = site.variant(id)?;
1614 let offset = site.offset(id)?;
1615 let (class, start) = if variant.length_type() == LengthType::Elongation {
1616 (
1617 first_of_kinds(variant.contents.events().iter().map(StreamEvent::element)),
1618 offset,
1619 )
1620 } else {
1621 (
1622 first_of_kinds(
1623 found
1624 .iter()
1625 .filter_map(|(found_id, _)| site.get(*found_id).map(|held| &held.element)),
1626 ),
1627 offset + variant.replacement_quarter_length(),
1628 )
1629 };
1630 let Some(class) = class else {
1631 return Ok(None);
1632 };
1633 Ok(site
1634 .in_span(start, Some(site.highest_time()), true)
1635 .into_iter()
1636 .find(|candidate| {
1637 site.get(*candidate)
1638 .is_some_and(|held| is_a(&held.element, class))
1639 }))
1640}
1641
1642fn previous_element(site: &Site, id: usize) -> Result<Option<usize>> {
1645 let found = replaced(site, id, &[], false, false)?;
1646 let variant = site.variant(id)?;
1647 let class = if variant.length_type() == LengthType::Elongation {
1648 first_of_kinds(variant.contents.events().iter().map(StreamEvent::element))
1649 } else {
1650 first_of_kinds(
1651 found
1652 .iter()
1653 .filter_map(|(found_id, _)| site.get(*found_id).map(|held| &held.element)),
1654 )
1655 };
1656 let class = class
1657 .ok_or_else(|| variant_error("Cannot find any Measures, Notes, or Rests in variant"))?;
1658 let offset = site.offset(id)?;
1659 Ok(site
1660 .in_span(0.0, Some(offset), false)
1661 .into_iter()
1662 .rfind(|candidate| {
1663 site.get(*candidate)
1664 .is_some_and(|held| is_a(&held.element, class))
1665 }))
1666}
1667
1668pub fn make_variant_blocks(stream: &mut Stream) -> Result<()> {
1679 let mut site = Site::of(stream);
1680 let mut failed = None;
1681 'variants: for id in site.variants() {
1682 let start = site.offset(id)?;
1683 let end = site.variant(id)?.replacement_quarter_length() + start;
1684 let conflicting: Vec<usize> = site
1685 .in_span(start, Some(end), false)
1686 .into_iter()
1687 .filter(|other| {
1688 matches!(
1689 site.get(*other).map(|held| &held.element),
1690 Some(StreamElement::Variant(_))
1691 )
1692 })
1693 .collect();
1694 for other in conflicting {
1695 let other_start = site.offset(other)?;
1696 if other_start == start {
1697 continue;
1698 }
1699 let shift = op_frac(other_start - start);
1700 let variant = site.variant_mut(other)?;
1701 let old = variant.replacement_quarter_length();
1702 shift_contents(&mut variant.contents, shift);
1703 let mut rest = Rest::new(Duration::new(shift)?);
1704 rest.set_hidden(true);
1705 put(&mut variant.contents, 0.0, StreamElement::Rest(rest));
1706 variant.replacement_quarter_length = Some(old);
1707 let moving = site
1708 .remove(other)
1709 .ok_or_else(|| variant_error("Variant not found in stream"))?;
1710 site.reinsert(moving, start);
1711 failed = Some(variant_error(
1712 "variants that overlap at different offsets cannot be made real",
1713 ));
1714 break 'variants;
1715 }
1716 }
1717 let (out, _) = site.finish(stream.clone());
1718 *stream = out;
1719 failed.map_or(Ok(()), Err)
1720}
1721
1722enum Renumber {
1726 Deleted(IntegerType),
1728 Inserted(Option<IntegerType>, Vec<usize>),
1730}
1731
1732impl Renumber {
1733 fn key(&self) -> IntegerType {
1734 match self {
1735 Self::Deleted(number) => *number,
1736 Self::Inserted(prior, _) => prior.unwrap_or(-9999),
1737 }
1738 }
1739}
1740
1741fn activate_replacement(site: &mut Site, id: usize, match_by_span: bool) -> Result<()> {
1744 let variant = site.variant(id)?.clone();
1745 let start = site.offset(id)?;
1746 let mut removed = Variant::named("default");
1747 if !match_by_span {
1748 let mut matched = 0;
1749 for event in variant.contents.events() {
1750 let exact = Exact::held(start).plus(Exact::held(event.offset()));
1753 let at = exact.to_float();
1754 let class = event.element().music21_classes()[0];
1755 let target = site.held.iter().find(|held| {
1756 is_a(&held.element, class)
1757 && at_offset(held.offset, length_of(&held.element), exact)
1758 });
1759 let target = target.map(|held| held.id);
1760 if let Some(target) = target {
1761 matched += 1;
1762 let taken = site
1763 .remove(target)
1764 .ok_or_else(|| variant_error("the element is not in the stream"))?;
1765 let mut element = event.element().clone();
1766 if let Some(number) = measure_number(&taken.element) {
1767 set_measure_number(&mut element, number);
1768 }
1769 removed.contents.push(taken.element);
1770 site.insert(at, element);
1771 }
1772 }
1773 if matched > 0 {
1774 site.remove(id);
1775 site.insert(start, removed.into());
1776 }
1777 return Ok(());
1778 }
1779 let mut deleted = VecDeque::new();
1780 for (target, _) in replaced(site, id, &[], false, false)? {
1781 let at = op_frac(site.offset(target)? - start);
1782 let taken = site
1783 .remove(target)
1784 .ok_or_else(|| variant_error("the element is not in the stream"))?;
1785 if let Some(number) = measure_number(&taken.element) {
1786 deleted.push_back(number);
1787 }
1788 put(&mut removed.contents, at, taken.element);
1789 }
1790 for event in variant.contents.events() {
1791 let mut element = event.element().clone();
1792 if is_measure(&element) {
1793 set_measure_number(&mut element, deleted.pop_front().unwrap_or(0));
1794 }
1795 site.insert(start + event.offset(), element);
1796 }
1797 site.remove(id);
1798 site.insert(start, removed.into());
1799 Ok(())
1800}
1801
1802fn activate_changed_length(
1808 site: &mut Site,
1809 id: usize,
1810 insertion: bool,
1811) -> Result<(Vec<IntegerType>, Renumber)> {
1812 let variant = site.variant(id)?.clone();
1813 let start = site.offset(id)?;
1814 let mut removed = Variant::named("default");
1815 removed.replacement_quarter_length = Some(variant.contained_highest_time());
1816 let mut deleted = VecDeque::new();
1817 for (target, _) in replaced(site, id, &[], false, false)? {
1818 let at = op_frac(site.offset(target)? - start);
1819 let taken = site
1820 .remove(target)
1821 .ok_or_else(|| variant_error("the element is not in the stream"))?;
1822 if let Some(number) = measure_number(&taken.element) {
1823 deleted.push_back(number);
1824 }
1825 put(&mut removed.contents, at, taken.element);
1826 }
1827 let mut highest = None;
1828 let mut inserted = Vec::new();
1829 for event in variant.contents.events() {
1830 let mut element = event.element().clone();
1831 let mut new_measure = false;
1832 if is_measure(&element) {
1833 match deleted.pop_front() {
1834 Some(number) => {
1835 set_measure_number(&mut element, number);
1836 highest = Some(number);
1837 }
1838 None => {
1839 set_measure_number(&mut element, 0);
1840 new_measure = true;
1841 }
1842 }
1843 }
1844 let new_id = site.insert(start + event.offset(), element);
1845 if new_measure {
1846 inserted.push(new_id);
1847 }
1848 }
1849 if insertion && highest.is_none() {
1850 let mut most = 0;
1851 for measure in site.in_span(0.0, Some(site.offset(id)?), true) {
1852 if let Some(number) = site
1853 .get(measure)
1854 .and_then(|held| measure_number(&held.element))
1855 && number > most
1856 {
1857 most = number;
1858 }
1859 }
1860 highest = Some(most);
1861 }
1862 site.remove(id);
1863 site.insert(start, removed.into());
1864 Ok((
1865 deleted.into_iter().collect(),
1866 Renumber::Inserted(highest, inserted),
1867 ))
1868}
1869
1870struct Opening<'a> {
1873 shift: FloatType,
1874 end: FloatType,
1875 include_end: bool,
1876 exempt: &'a Vec<usize>,
1877 exempt_shift: FloatType,
1878}
1879
1880fn shift_gaps(site: &mut Site, gaps: &[(FloatType, FloatType, Vec<usize>)], remove: bool) {
1884 let duration = site.highest_time();
1885 let mut sorted: Vec<&(FloatType, FloatType, Vec<usize>)> = gaps.iter().collect();
1886 sorted.sort_by(|left, right| left.0.total_cmp(&right.0));
1887 let bounds = |i: usize| -> (FloatType, bool) {
1888 match sorted.get(i + 1) {
1889 Some(next) => (next.0, false),
1890 None => (duration, true),
1891 }
1892 };
1893 if remove {
1894 let mut shift = 0.0;
1895 for (i, (start, amount, exempt)) in sorted.iter().enumerate() {
1896 let (end, include_end) = bounds(i);
1897 shift += amount;
1898 for id in site.in_span(start + amount, Some(end), include_end) {
1899 if exempt.contains(&id) {
1900 continue;
1901 }
1902 if let Some(held) = site.get_mut(id) {
1903 held.offset = op_frac(held.offset - shift);
1904 }
1905 }
1906 }
1907 } else {
1908 let mut shift = 0.0;
1909 let mut shifts: Vec<(FloatType, Opening<'_>)> = Vec::new();
1911 for (i, (start, amount, exempt)) in sorted.iter().enumerate() {
1912 let (end, include_end) = bounds(i);
1913 let exempt_shift = shift;
1914 shift += amount;
1915 let entry = Opening {
1916 shift,
1917 end,
1918 include_end,
1919 exempt,
1920 exempt_shift,
1921 };
1922 match shifts.iter_mut().find(|(known, _)| known == start) {
1923 Some((_, held)) => *held = entry,
1924 None => shifts.push((*start, entry)),
1925 }
1926 }
1927 shifts.sort_by(|left, right| right.0.total_cmp(&left.0));
1928 for (offset, opening) in shifts {
1929 for id in site.in_span(offset, Some(opening.end), opening.include_end) {
1930 let by = if opening.exempt.contains(&id) {
1931 opening.exempt_shift
1932 } else {
1933 opening.shift
1934 };
1935 if let Some(held) = site.get_mut(id) {
1936 held.offset = op_frac(held.offset + by);
1937 }
1938 }
1939 }
1940 }
1941 site.sort();
1942}
1943
1944fn fix_measure_numbers(site: &mut Site, mut all: Vec<Renumber>) -> Result<()> {
1946 if all.is_empty() {
1947 return Ok(());
1948 }
1949 all.sort_by_key(Renumber::key);
1950 let mut old_measures = site.measures();
1951 let mut new_measures: Vec<usize> = Vec::new();
1952 let mut cumulative: IntegerType = 0;
1953 let mut old_corrections: Vec<(IntegerType, IntegerType)> = Vec::new();
1954 let mut new_corrections: Vec<(IntegerType, IntegerType)> = Vec::new();
1955 let correct =
1956 |corrections: &mut Vec<(IntegerType, IntegerType)>, at: IntegerType, by: IntegerType| {
1957 match corrections.iter_mut().find(|(known, _)| *known == at) {
1958 Some((_, held)) => *held = by,
1959 None => corrections.push((at, by)),
1960 }
1961 };
1962 for entry in all {
1963 match entry {
1964 Renumber::Inserted(prior, measures) => {
1965 if measures.is_empty() {
1966 continue;
1967 }
1968 let prior = prior.ok_or_else(|| {
1969 variant_error("measures inserted before any numbered measure")
1970 })?;
1971 cumulative += measures.len() as IntegerType;
1972 let mut next = prior + 1;
1973 for id in measures {
1974 old_measures.retain(|known| *known != id);
1976 new_measures.push(id);
1977 if let Some(held) = site.get_mut(id) {
1978 set_measure_number(&mut held.element, next);
1979 }
1980 next += 1;
1981 }
1982 correct(&mut old_corrections, prior + 1, cumulative);
1983 correct(&mut new_corrections, next, cumulative);
1984 }
1985 Renumber::Deleted(number) => {
1986 cumulative -= 1;
1987 correct(&mut old_corrections, number + 1, cumulative);
1988 correct(&mut new_corrections, number + 1, cumulative);
1989 }
1990 }
1991 }
1992 for (measures, corrections) in [
1993 (old_measures, old_corrections),
1994 (new_measures, new_corrections),
1995 ] {
1996 let mut corrections = corrections;
1997 corrections.sort_by_key(|(at, _)| -*at);
1998 let mut previous: Option<IntegerType> = None;
1999 for (at, shift) in corrections {
2000 for &id in &measures {
2001 let Some(held) = site.get_mut(id) else {
2002 continue;
2003 };
2004 let Some(number) = measure_number(&held.element) else {
2005 continue;
2006 };
2007 if previous.is_none_or(|boundary| number < boundary) && number >= at {
2008 set_measure_number(&mut held.element, number + shift);
2009 }
2010 }
2011 previous = Some(at);
2012 }
2013 }
2014 Ok(())
2015}
2016
2017impl Stream {
2018 pub fn activate_variants(&self, group: Option<&str>, match_by_span: bool) -> Result<Stream> {
2043 let mut site = Site::of(self);
2044 let (mut elongations, mut deletions) = (Vec::new(), Vec::new());
2045 for id in site.variants() {
2046 let variant = site.variant(id)?;
2047 if group.is_some_and(|group| !variant.groups.iter().any(|known| known == group)) {
2048 continue;
2049 }
2050 match variant.length_type() {
2051 LengthType::Elongation => elongations.push(id),
2052 LengthType::Deletion => deletions.push(id),
2053 LengthType::Replacement => activate_replacement(&mut site, id, match_by_span)?,
2054 }
2055 }
2056 let mut deleted: Vec<Renumber> = Vec::new();
2057 let mut inserted: Vec<Renumber> = Vec::new();
2058 let mut gaps = Vec::new();
2059 for id in deletions {
2060 let variant = site.variant(id)?;
2061 let difference =
2062 variant.replacement_quarter_length() - variant.contained_highest_time();
2063 let start = site.offset(id)? + variant.contained_highest_time();
2064 let (left, renumber) = activate_changed_length(&mut site, id, false)?;
2065 gaps.push((start, difference, Vec::new()));
2066 deleted.extend(left.into_iter().map(Renumber::Deleted));
2067 inserted.push(renumber);
2068 }
2069 shift_gaps(&mut site, &gaps, true);
2070 let mut openings = Vec::new();
2071 for &id in &elongations {
2072 let variant = site.variant(id)?;
2073 let difference =
2074 variant.replacement_quarter_length() - variant.contained_highest_time();
2075 let start = site.offset(id)? + variant.replacement_quarter_length();
2076 openings.push((start, -difference, vec![id]));
2077 }
2078 shift_gaps(&mut site, &openings, false);
2079 for id in elongations {
2080 let (left, renumber) = activate_changed_length(&mut site, id, true)?;
2081 inserted.push(renumber);
2082 deleted.extend(left.into_iter().map(Renumber::Deleted));
2083 }
2084 deleted.extend(inserted);
2085 fix_measure_numbers(&mut site, deleted)?;
2086 Ok(site.finish(self.clone()).0)
2087 }
2088
2089 pub fn show_variant_as_ossialike_part(
2099 &self,
2100 part: usize,
2101 variant_groups: &[&str],
2102 ) -> Result<Stream> {
2103 let mut out = self.clone();
2104 let source = self
2105 .parts()
2106 .get(part)
2107 .map(|found| (*found).clone())
2108 .ok_or_else(|| variant_error("Could not find the part in the score"))?;
2109 for group in variant_groups {
2110 let mut expressed = false;
2111 let mut held: Vec<(usize, StreamEvent, Option<usize>)> = Vec::new();
2114 let mut later = source.events().len();
2115 for (index, event) in source.events().iter().enumerate() {
2116 match event.element() {
2117 StreamElement::Variant(variant) => {
2118 if !variant.groups.iter().any(|known| known == group)
2119 || matches!(
2120 variant.length_type(),
2121 LengthType::Elongation | LengthType::Deletion
2122 )
2123 {
2124 continue;
2125 }
2126 expressed = true;
2127 held.push((index, event.clone(), Some(index)));
2128 }
2129 element if is_general_note(element) => {
2130 let mut rest = Rest::new(Duration::new(element.quarter_length())?);
2131 rest.set_hidden(true);
2132 held.push((
2133 later,
2134 StreamEvent::new(event.offset(), StreamElement::Rest(rest)),
2135 None,
2136 ));
2137 later += 1;
2138 }
2139 StreamElement::Stream(measure) if measure.kind() == StreamKind::Measure => {
2140 let length = highest_time(measure);
2141 let mut emptied = (**measure).clone();
2142 let kept: Vec<(StreamEvent, Option<usize>)> = emptied
2143 .events()
2144 .iter()
2145 .enumerate()
2146 .filter(|(_, inner)| !is_general_note(inner.element()))
2147 .map(|(at, inner)| (inner.clone(), Some(at)))
2148 .collect();
2149 emptied.replace_events(kept);
2150 let mut rest = Rest::new(Duration::new(length)?);
2151 rest.set_hidden(true);
2152 put(&mut emptied, 0.0, StreamElement::Rest(rest));
2153 held.push((
2154 index,
2155 StreamEvent::new(
2156 event.offset(),
2157 StreamElement::Stream(Box::new(emptied)),
2158 ),
2159 Some(index),
2160 ));
2161 }
2162 _ => held.push((index, event.clone(), Some(index))),
2163 }
2164 }
2165 held.sort_by(|left, right| {
2166 crate::makenotation::event_order(&left.1, &right.1).then(left.0.cmp(&right.0))
2167 });
2168 let mut new_part = source.clone();
2169 new_part.replace_events(
2170 held.into_iter()
2171 .map(|(_, event, origin)| (event, origin))
2172 .collect(),
2173 );
2174 let new_part = new_part.activate_variants(Some(group), true)?;
2175 if expressed {
2176 out.insert_sorted(vec![StreamEvent::new(
2177 0.0,
2178 StreamElement::Stream(Box::new(new_part)),
2179 )]);
2180 }
2181 }
2182 Ok(out)
2183 }
2184}