Skip to content

Commit

Permalink
Display charms on /sat (ordinals#3340)
Browse files Browse the repository at this point in the history
  • Loading branch information
markovichecha authored Mar 23, 2024
1 parent e2023e7 commit a0de74b
Show file tree
Hide file tree
Showing 16 changed files with 230 additions and 165 deletions.
5 changes: 4 additions & 1 deletion bin/forbid
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

set -euo pipefail

which rg > /dev/null
if ! which rg > /dev/null; then
echo "error: ripgrep (rg) not found"
exit 1
fi

! rg \
--glob '!bin/forbid' \
Expand Down
148 changes: 148 additions & 0 deletions crates/ordinals/src/charm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
use super::*;

#[derive(Copy, Clone, Debug, PartialEq, DeserializeFromStr, SerializeDisplay)]
pub enum Charm {
Coin = 0,
Cursed = 1,
Epic = 2,
Legendary = 3,
Lost = 4,
Nineball = 5,
Rare = 6,
Reinscription = 7,
Unbound = 8,
Uncommon = 9,
Vindicated = 10,
Mythic = 11,
}

impl Charm {
pub const ALL: [Charm; 12] = [
Self::Coin,
Self::Uncommon,
Self::Rare,
Self::Epic,
Self::Legendary,
Self::Mythic,
Self::Nineball,
Self::Reinscription,
Self::Cursed,
Self::Unbound,
Self::Lost,
Self::Vindicated,
];

fn flag(self) -> u16 {
1 << self as u16
}

pub fn set(self, charms: &mut u16) {
*charms |= self.flag();
}

pub fn is_set(self, charms: u16) -> bool {
charms & self.flag() != 0
}

pub fn unset(self, charms: u16) -> u16 {
charms & !self.flag()
}

pub fn icon(self) -> &'static str {
match self {
Self::Coin => "🪙",
Self::Cursed => "👹",
Self::Epic => "🪻",
Self::Legendary => "🌝",
Self::Lost => "🤔",
Self::Mythic => "🎃",
Self::Nineball => "9️⃣",
Self::Rare => "🧿",
Self::Reinscription => "♻️",
Self::Unbound => "🔓",
Self::Uncommon => "🌱",
Self::Vindicated => "❤️‍🔥",
}
}

pub fn charms(charms: u16) -> Vec<Charm> {
Self::ALL
.iter()
.filter(|charm| charm.is_set(charms))
.copied()
.collect()
}
}

impl Display for Charm {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(
f,
"{}",
match self {
Self::Coin => "coin",
Self::Cursed => "cursed",
Self::Epic => "epic",
Self::Legendary => "legendary",
Self::Lost => "lost",
Self::Mythic => "mythic",
Self::Nineball => "nineball",
Self::Rare => "rare",
Self::Reinscription => "reinscription",
Self::Unbound => "unbound",
Self::Uncommon => "uncommon",
Self::Vindicated => "vindicated",
}
)
}
}

impl FromStr for Charm {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"coin" => Self::Coin,
"cursed" => Self::Cursed,
"epic" => Self::Epic,
"legendary" => Self::Legendary,
"lost" => Self::Lost,
"mythic" => Self::Mythic,
"nineball" => Self::Nineball,
"rare" => Self::Rare,
"reinscription" => Self::Reinscription,
"unbound" => Self::Unbound,
"uncommon" => Self::Uncommon,
"vindicated" => Self::Vindicated,
_ => return Err(format!("invalid charm `{s}`")),
})
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn flag() {
assert_eq!(Charm::Coin.flag(), 0b1);
assert_eq!(Charm::Cursed.flag(), 0b10);
}

#[test]
fn set() {
let mut flags = 0;
assert!(!Charm::Coin.is_set(flags));
Charm::Coin.set(&mut flags);
assert!(Charm::Coin.is_set(flags));
}

#[test]
fn unset() {
let mut flags = 0;
Charm::Coin.set(&mut flags);
assert!(Charm::Coin.is_set(flags));
let flags = Charm::Coin.unset(flags);
assert!(!Charm::Coin.is_set(flags));
}
}
5 changes: 3 additions & 2 deletions crates/ordinals/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ use {
pub const CYCLE_EPOCHS: u32 = 6;

pub use {
decimal_sat::DecimalSat, degree::Degree, epoch::Epoch, height::Height, rarity::Rarity, sat::Sat,
sat_point::SatPoint,
charm::Charm, decimal_sat::DecimalSat, degree::Degree, epoch::Epoch, height::Height,
rarity::Rarity, sat::Sat, sat_point::SatPoint,
};

mod charm;
mod decimal_sat;
mod degree;
mod epoch;
Expand Down
23 changes: 23 additions & 0 deletions crates/ordinals/src/sat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,29 @@ impl Sat {
name.chars().rev().collect()
}

pub fn charms(self) -> u16 {
let mut charms = 0;

if self.nineball() {
Charm::Nineball.set(&mut charms);
}

if self.coin() {
Charm::Coin.set(&mut charms);
}

match self.rarity() {
Rarity::Common => {}
Rarity::Epic => Charm::Epic.set(&mut charms),
Rarity::Legendary => Charm::Legendary.set(&mut charms),
Rarity::Mythic => Charm::Mythic.set(&mut charms),
Rarity::Rare => Charm::Rare.set(&mut charms),
Rarity::Uncommon => Charm::Uncommon.set(&mut charms),
}

charms
}

fn from_name(s: &str) -> Result<Self, Error> {
let mut x = 0;
for c in s.chars() {
Expand Down
19 changes: 10 additions & 9 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ pub struct Children {
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct Inscription {
pub address: Option<String>,
pub charms: Vec<String>,
pub charms: Vec<Charm>,
pub children: Vec<InscriptionId>,
pub content_length: Option<usize>,
pub content_type: Option<String>,
Expand All @@ -96,7 +96,7 @@ pub struct Inscription {

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct InscriptionRecursive {
pub charms: Vec<String>,
pub charms: Vec<Charm>,
pub content_type: Option<String>,
pub content_length: Option<usize>,
pub fee: u64,
Expand Down Expand Up @@ -160,20 +160,21 @@ impl Output {

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Sat {
pub number: u64,
pub decimal: String,
pub degree: String,
pub name: String,
pub block: u32,
pub charms: Vec<Charm>,
pub cycle: u32,
pub decimal: String,
pub degree: String,
pub epoch: u32,
pub period: u32,
pub inscriptions: Vec<InscriptionId>,
pub name: String,
pub number: u64,
pub offset: u64,
pub rarity: Rarity,
pub percentile: String,
pub period: u32,
pub rarity: Rarity,
pub satpoint: Option<SatPoint>,
pub timestamp: i64,
pub inscriptions: Vec<InscriptionId>,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
Expand Down
16 changes: 1 addition & 15 deletions src/index/updater/inscription_updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,21 +462,7 @@ impl<'a, 'tx> InscriptionUpdater<'a, 'tx> {
}

if let Some(sat) = sat {
if sat.nineball() {
Charm::Nineball.set(&mut charms);
}

if sat.coin() {
Charm::Coin.set(&mut charms);
}

match sat.rarity() {
Rarity::Common | Rarity::Mythic => {}
Rarity::Uncommon => Charm::Uncommon.set(&mut charms),
Rarity::Rare => Charm::Rare.set(&mut charms),
Rarity::Epic => Charm::Epic.set(&mut charms),
Rarity::Legendary => Charm::Legendary.set(&mut charms),
}
charms |= sat.charms();
}

if new_satpoint.outpoint == OutPoint::null() {
Expand Down
3 changes: 1 addition & 2 deletions src/inscriptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ use super::*;

use tag::Tag;

pub(crate) use self::{charm::Charm, envelope::ParsedEnvelope, media::Media};
pub(crate) use self::{envelope::ParsedEnvelope, media::Media};

pub use self::{envelope::Envelope, inscription::Inscription, inscription_id::InscriptionId};

mod charm;
mod envelope;
mod inscription;
pub(crate) mod inscription_id;
Expand Down
Loading

0 comments on commit a0de74b

Please sign in to comment.