use std::fmt::Debug; use crate::Token; /// Given two lists of tokens, returns `length` where the `old` list /// somewhere within contains the `length` prefix of the `new` list. /// /// ## Example /// /// ```not_rust /// old: [0, 1, 9, 0, 2, 5] /// new: [9, 0, 2, 5, 1] /// ``` /// > results in a length of 4 /// /// /// ```not_rust /// old: [0, 1, 9, 0, 2, 5] /// new: [0, 2] /// ``` /// > results in a length of 2 /// /// ```not_rust /// old: [0, 1, 9, 0, 2, 5] /// new: [0, 4] /// ``` /// > results in a length of 1 pub fn find_longest_prefix_contained_within(old: &[Token], new: &[Token]) -> usize where T: PartialEq + Clone + Debug, { let max_possible = new.len().min(old.len()); for len in (1..=max_possible).rev() { let prefix = &new[..len]; if old.windows(len).any(|window| window == prefix) { return len; } } 0 } #[cfg(test)] mod tests { use pretty_assertions::assert_eq; use super::*; #[test] fn test_common_overlap() { assert_eq!( find_longest_prefix_contained_within(&["".into()], &["".into()]), 1 ); assert_eq!( find_longest_prefix_contained_within( &["a".into(), "b".into(), "c".into()], &["b".into(), "c".into(), "a".into()] ), 2 ); assert_eq!( find_longest_prefix_contained_within( &["a".into(), "b".into(), "c".into()], &["b".into(), "c".into()] ), 2 ); assert_eq!( find_longest_prefix_contained_within( &["a".into(), "b".into(), "c".into()], &["b".into()] ), 1 ); assert_eq!( find_longest_prefix_contained_within( &["a".into(), "b".into(), "c".into(), "b".into(), "a".into()], &["b".into(), "a".into()] ), 2 ); assert_eq!( find_longest_prefix_contained_within( &["a".into(), "a".into(), "a".into()], &["a".into(), "b".into(), "c".into()] ), 1 ); assert_eq!( find_longest_prefix_contained_within( &["a".into(), "b".into(), "c".into()], &["d".into(), "e".into(), "a".into()] ), 0 ); } }