x = x * 26 + c as u64 - 'a' as u64 + 1;
if x > Self::SUPPLY {
bail!("sat name out of range");
}
}
_ => bail!("invalid character in sat name: {c}"),
}
}
Ok(Sat(Self::SUPPLY - x))
}
fn from_degree(degree: &str) -> Result<Self> {
let (cycle_number, rest) = degree
.split_once('°')
.ok_or_else(|| anyhow!("missing degree symbol"))?;
let cycle_number = cycle_number.parse::<u32>()?;
let (epoch_offset, rest) = rest
.split_once('′')
.ok_or_else(|| anyhow!("missing minute symbol"))?;
let epoch_offset = epoch_offset.parse::<u32>()?;
if epoch_offset >= SUBSIDY_HALVING_INTERVAL {
bail!("invalid epoch offset");
}
let (period_offset, rest) = rest
.split_once('″')
.ok_or_else(|| anyhow!("missing second symbol"))?;
let period_offset = period_offset.parse::<u32>()?;
if period_offset >= DIFFCHANGE_INTERVAL {
bail!("invalid period offset");
}
let cycle_start_epoch = cycle_number * CYCLE_EPOCHS;