Skip to content

Commit

Permalink
support v2 emotes
Browse files Browse the repository at this point in the history
  • Loading branch information
Emilgardis committed Dec 3, 2022
1 parent 8832305 commit 1a99c92
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 9 deletions.
3 changes: 3 additions & 0 deletions src/maybe_owned/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub use maybe_owned_index::MaybeOwnedIndex;
///
/// This only exposed for people to extend messages themselves.
#[cfg_attr(feature = "serde", derive(::serde::Serialize), serde(untagged))]
#[derive(Hash)]
pub enum MaybeOwned<'a> {
/// Owned variant, a `Box<str>`. This usually means it has a `'static` lifetime
Owned(Box<str>),
Expand Down Expand Up @@ -59,6 +60,8 @@ impl<'a> PartialEq for MaybeOwned<'a> {
}
}

impl<'a> Eq for MaybeOwned<'a> {}

impl<'a> PartialEq<str> for MaybeOwned<'a> {
fn eq(&self, other: &str) -> bool {
self.as_ref() == other
Expand Down
2 changes: 1 addition & 1 deletion src/messages/privmsg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub struct EmotesIter<'a> {
}

impl<'a> Iterator for EmotesIter<'a> {
type Item = Emotes;
type Item = Emotes<'a>;

fn next(&mut self) -> Option<Self::Item> {
if let Some(item) = self.items.as_mut()?.next() {
Expand Down
33 changes: 25 additions & 8 deletions src/twitch/emotes.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::ops::Range;

use crate::maybe_owned::MaybeOwned;

/**
Emotes are little pictograms used in-line in Twitch messages
Expand All @@ -12,33 +14,43 @@ They are presented (to the irc connection) in a `id:range1,range2/id2:range1,..`
*/
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
pub struct Emotes {
/// This emote id, e.g. `Kappa = 25`
pub id: usize,
pub struct Emotes<'a> {
/// This emote id, e.g. `Kappa = 25`
pub id: MaybeOwned<'a>,
/// A list of [Range] in the message where this emote is found
///
/// [Range]: https://doc.rust-lang.org/std/ops/struct.Range.html
pub ranges: Vec<Range<u16>>,
}

impl Emotes {
impl<'a> Emotes<'a> {
/// Parse emotes from a string, returning an iterator over each emote
pub fn parse(input: &str) -> impl Iterator<Item = Self> + '_ {
pub fn parse(input: &'a str) -> impl Iterator<Item = Emotes<'a>> + 'a {
input.split_terminator('/').filter_map(Self::parse_item)
}

/// Parse single emote
pub fn parse_item(item: &str) -> Option<Self> {
pub fn parse_item(item: &'a str) -> Option<Self> {
get_parts(item, ':').and_then(|(head, tail)| {
let emotes = Self {
id: head.parse().ok()?,
id: head.into(),
ranges: get_ranges(tail).collect(),
};
emotes.into()
})
}
}

impl<'a> crate::IntoOwned<'a> for Emotes<'a> {
type Output = Emotes<'static>;
fn into_owned(self) -> Self::Output {
Emotes {
id: self.id.into_owned(),
ranges: self.ranges,
}
}
}

#[inline]
fn get_parts(input: &str, sep: char) -> Option<(&str, &str)> {
let mut split = input.split_terminator(sep);
Expand All @@ -64,10 +76,11 @@ mod tests {
macro_rules! emote {
($id:expr, $($r:expr),* $(,)?) => {
Emotes {
id: $id,
id: $id.to_string().into(),
ranges: vec![$($r),*]
}
};

}

let inputs = &[
Expand Down Expand Up @@ -95,6 +108,10 @@ mod tests {
"33:0-7/25:9-13,15-19",
vec![emote!(33, (0..7)), emote!(25, (9..13), (15..19))],
),
(
"emotesv2_4c3b4ed516de493bbcd2df2f5d450f49:0-25",
vec![emote!("emotesv2_4c3b4ed516de493bbcd2df2f5d450f49", (0..25))],
),
];

for (input, expect) in inputs {
Expand Down

0 comments on commit 1a99c92

Please sign in to comment.