use std::fmt::{Debug, Formatter};
use std::str::FromStr;
use fixedbitset::FixedBitSet;
use crate::Graph6Error;
use crate::utils::{fill_bitset, get_size};
#[derive(Clone)]
pub struct DiGraph6 {
nodes: usize,
bitset: FixedBitSet,
}
impl Debug for DiGraph6 {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("digraph6")
.field("nodes", &self.nodes())
.field("edges", &self.edges())
.field("adjacency", &self.bitset.to_string())
.finish()
}
}
impl FromStr for DiGraph6 {
type Err = Graph6Error;
fn from_str(s: &str) -> Result<Self, Graph6Error> {
let bytes = remove_head(s.as_bytes())?;
let (nodes, bytes) = get_size(bytes)?;
let bitset = fill_bitset(bytes, nodes * nodes)?;
Ok(DiGraph6 {
nodes,
bitset,
})
}
}
impl DiGraph6 {
pub fn nodes(&self) -> usize {
self.nodes
}
pub fn edges(&self) -> usize {
self.bitset.ones().count()
}
}
fn remove_head(bytes: &[u8]) -> Result<&[u8], Graph6Error> {
if bytes.starts_with(b">>digraph6<<&") {
Ok(&bytes[13..])
} else if bytes.starts_with(b"&") {
Ok(&bytes[1..])
} else {
Err(Graph6Error::InvalidHeader { except: "&" })
}
}