Skip to content

Commit

Permalink
polish
Browse files Browse the repository at this point in the history
  • Loading branch information
yegor256 committed Mar 19, 2023
1 parent 119cbd9 commit 6c91fa8
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 59 deletions.
2 changes: 1 addition & 1 deletion src/dot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ use anyhow::Result;
fn simple_graph_to_dot() -> Result<()> {
let mut g = Sodg::empty();
g.add(0)?;
g.put(0, Hex::from_str_bytes("hello"))?;
g.put(0, &Hex::from_str_bytes("hello"))?;
g.add(1)?;
g.bind(0, 1, "foo")?;
let dot = g.to_dot();
Expand Down
48 changes: 24 additions & 24 deletions src/hex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ impl Hex {
/// assert!(d.is_empty());
/// assert_eq!("--", d.print());
/// ```
#[must_use]
pub fn empty() -> Self {
Self::from_vec(Vec::new())
}
Expand All @@ -67,10 +68,11 @@ impl Hex {
/// let d = Hex::from(2);
/// assert_eq!(8, d.len())
/// ```
#[must_use]
pub fn bytes(&self) -> &[u8] {
match self {
Hex::Vector(v) => v,
Hex::Bytes(array, size) => &array[..*size],
Self::Vector(v) => v,
Self::Bytes(array, size) => &array[..*size],
}
}

Expand All @@ -91,10 +93,11 @@ impl Hex {
/// let d = Hex::from(42);
/// assert_eq!(8, d.len());
/// ```
#[must_use]
pub fn len(&self) -> usize {
match self {
Hex::Vector(x) => x.len(),
Hex::Bytes(_, size) => *size,
Self::Vector(x) => x.len(),
Self::Bytes(_, size) => *size,
}
}

Expand All @@ -109,6 +112,7 @@ impl Hex {
/// let v = Hex::from_slice(&vec![0xBE, 0xEF]);
/// assert_eq!("BE-EF", v.print());
/// ```
#[must_use]
pub fn from_slice(slice: &[u8]) -> Self {
if slice.len() <= 24 {
Self::Bytes(
Expand All @@ -133,6 +137,7 @@ impl Hex {
/// let d = Hex::from_vec(vec![0xCA, 0xFE]);
/// assert_eq!("CA-FE", d.print());
/// ```
#[must_use]
pub fn from_vec(bytes: Vec<u8>) -> Self {
if bytes.len() <= 24 {
Self::from_slice(&bytes)
Expand All @@ -141,19 +146,6 @@ impl Hex {
}
}

/// Create a new [`Hex`] from `String`.
///
/// For example:
///
/// ```
/// use sodg::Hex;
/// let d = Hex::from_string_bytes("Ура!".to_string());
/// assert_eq!("D0-A3-D1-80-D0-B0-21", d.print());
/// ```
pub fn from_string_bytes(d: String) -> Self {
Self::from_slice(d.as_bytes())
}

/// Create a new [`Hex`] from the bytes composing `&str`.
///
/// For example:
Expand All @@ -163,6 +155,7 @@ impl Hex {
/// let d = Hex::from_str_bytes("Ура!");
/// assert_eq!("D0-A3-D1-80-D0-B0-21", d.print());
/// ```
#[must_use]
pub fn from_str_bytes(d: &str) -> Self {
Self::from_slice(d.as_bytes())
}
Expand All @@ -176,6 +169,7 @@ impl Hex {
/// let d = Hex::from_vec(vec![]);
/// assert_eq!(true, d.is_empty());
/// ```
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
Expand All @@ -189,6 +183,7 @@ impl Hex {
/// let d = Hex::from_vec([0x01].to_vec());
/// assert_eq!(true, d.to_bool().unwrap());
/// ```
#[must_use]
pub fn to_bool(&self) -> bool {
self.bytes()[0] == 0x01
}
Expand Down Expand Up @@ -280,6 +275,7 @@ impl Hex {
/// let d = Hex::empty();
/// assert_eq!("--", d.print());
/// ```
#[must_use]
pub fn print(&self) -> String {
if self.bytes().is_empty() {
"--".to_string()
Expand All @@ -293,6 +289,7 @@ impl Hex {
}

/// Turn it into a vector of bytes (making a clone).
#[must_use]
pub fn to_vec(&self) -> Vec<u8> {
self.bytes().to_vec()
}
Expand All @@ -307,6 +304,7 @@ impl Hex {
/// assert_eq!("E4-BD-A0-E5-A5-BD", d.print());
/// assert_eq!(0xA0, d.byte_at(2));
/// ```
#[must_use]
pub fn byte_at(&self, pos: usize) -> u8 {
self.bytes()[pos]
}
Expand All @@ -321,6 +319,7 @@ impl Hex {
/// let d = Hex::from_str_bytes("Hello, world!");
/// assert_eq!("world!", d.tail(7).to_utf8().unwrap());
/// ```
#[must_use]
pub fn tail(&self, skip: usize) -> Self {
Self::from_vec(self.bytes()[skip..].to_vec())
}
Expand All @@ -333,26 +332,27 @@ impl Hex {
/// use sodg::Hex;
/// let a = Hex::from_slice("dead".as_bytes());
/// let b = Hex::from_slice("beef".as_bytes());
/// let c = a.concat(b);
/// let c = a.concat(&b);
/// assert_eq!(c, Hex::from_slice("deadbeef".as_bytes()));
/// ```
pub fn concat(&self, h: Self) -> Self {
#[must_use]
pub fn concat(&self, h: &Self) -> Self {
match &self {
Hex::Vector(v) => {
Self::Vector(v) => {
let mut vx = v.clone();
vx.extend_from_slice(h.bytes());
Hex::Vector(vx)
Self::Vector(vx)
}
Hex::Bytes(b, l) => {
Self::Bytes(b, l) => {
if l + h.len() <= 24 {
let mut bytes = *b;
bytes[*l..*l + h.len()].copy_from_slice(h.bytes());
Hex::Bytes(bytes, l + h.len())
Self::Bytes(bytes, l + h.len())
} else {
let mut v = Vec::new();
v.extend_from_slice(b);
v.extend_from_slice(h.bytes());
Hex::Vector(v)
Self::Vector(v)
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/inspect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl Sodg {
if skip {
"…".to_string()
} else {
"".to_string()
String::new()
}
);
lines.push(line);
Expand All @@ -87,7 +87,7 @@ use crate::Hex;
fn inspects_simple_object() -> Result<()> {
let mut g = Sodg::empty();
g.add(0)?;
g.put(0, Hex::from_str_bytes("hello"))?;
g.put(0, &Hex::from_str_bytes("hello"))?;
g.add(1)?;
g.bind(0, 1, "foo")?;
let txt = g.inspect("")?;
Expand Down
28 changes: 14 additions & 14 deletions src/merge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,18 @@ impl Sodg {
/// # Errors
///
/// If it's impossible to merge, an error will be returned.
pub fn merge(&mut self, g: &Sodg, left: u32, right: u32) -> Result<()> {
pub fn merge(&mut self, g: &Self, left: u32, right: u32) -> Result<()> {
let mut mapped = HashMap::new();
let before = self.vertices.len();
self.merge_rec(g, left, right, &mut mapped)?;
let merged = mapped.len();
let scope = g.vertices.len();
if merged != scope {
let must: Vec<u32> = g.vertices.keys().cloned().collect();
let seen: Vec<u32> = mapped.keys().cloned().collect();
let must: Vec<u32> = g.vertices.keys().copied().collect();
let seen: Vec<u32> = mapped.keys().copied().collect();
let missed: HashSet<u32> = &HashSet::from_iter(must) - &HashSet::from_iter(seen);
let mut ordered: Vec<u32> = missed.into_iter().collect();
ordered.sort();
ordered.sort_unstable();
return Err(anyhow!(
"Just {merged} vertices merged, out of {scope}; maybe the right graph was not a tree? {} missed: {}",
ordered.len(), ordered.iter().map(|v| format!("ν{v}")).collect::<Vec<String>>().join(", ")
Expand All @@ -76,7 +76,7 @@ impl Sodg {
/// If it's impossible to merge, an error will be returned.
fn merge_rec(
&mut self,
g: &Sodg,
g: &Self,
left: u32,
right: u32,
mapped: &mut HashMap<u32, u32>,
Expand All @@ -88,11 +88,11 @@ impl Sodg {
let d = g
.vertices
.get(&right)
.ok_or(anyhow!("Can't find ν{right} in the right graph"))?
.ok_or_else(|| anyhow!("Can't find ν{right} in the right graph"))?
.data
.clone();
if !d.is_empty() {
self.put(left, d)?;
self.put(left, &d)?;
}
for (a, to) in g.kids(right)? {
let lft = if let Some(t) = self.kid(left, &a) {
Expand All @@ -106,13 +106,13 @@ impl Sodg {
self.bind(left, id, &a)?;
id
};
self.merge_rec(g, lft, to, mapped)?
self.merge_rec(g, lft, to, mapped)?;
}
for (a, to) in g.kids(right)? {
if let Some(first) = self.kid(left, &a) {
if let Some(second) = mapped.get(&to) {
if first != *second {
self.join(first, *second)?
self.join(first, *second)?;
}
}
}
Expand All @@ -121,8 +121,8 @@ impl Sodg {
}

fn join(&mut self, left: u32, right: u32) -> Result<()> {
for vtx in self.vertices.iter_mut() {
for e in vtx.1.edges.iter_mut() {
for vtx in &mut self.vertices {
for e in &mut vtx.1.edges {
if e.to == right {
e.to = left;
}
Expand Down Expand Up @@ -292,7 +292,7 @@ fn merges_data() -> Result<()> {
g.add(1)?;
let mut extra = Sodg::empty();
extra.add(1)?;
extra.put(1, Hex::from(42))?;
extra.put(1, &Hex::from(42))?;
g.merge(&extra, 1, 1)?;
assert_eq!(42, g.data(1)?.to_i64()?);
Ok(())
Expand Down Expand Up @@ -342,9 +342,9 @@ fn mixed_injection() -> Result<()> {
g.add(4)?;
let mut extra = Sodg::empty();
extra.add(4)?;
extra.put(4, Hex::from(4))?;
extra.put(4, &Hex::from(4))?;
extra.add(5)?;
extra.put(5, Hex::from(5))?;
extra.put(5, &Hex::from(5))?;
extra.bind(4, 5, "b")?;
g.merge(&extra, 4, 4)?;
assert_eq!(2, g.vertices.len());
Expand Down
3 changes: 3 additions & 0 deletions src/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ use crate::Sodg;

impl Sodg {
/// Get total number of vertices in the graph.
#[must_use]
pub fn len(&self) -> usize {
self.vertices.len()
}

/// Get all IDs of vertices, in a vector.
#[must_use]
pub fn ids(&self) -> Vec<u32> {
self.vertices.keys().copied().collect()
}
Expand All @@ -44,6 +46,7 @@ impl Sodg {
/// sodg.add(42).unwrap();
/// sodg.bind(0, 42, "hello").unwrap();
/// ```
#[must_use]
pub fn is_empty(&self) -> bool {
self.vertices.is_empty()
}
Expand Down
13 changes: 5 additions & 8 deletions src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,13 @@ impl Sodg {
/// use sodg::Sodg;
/// let mut g = Sodg::empty();
/// g.add(42).unwrap();
/// g.put(42, Hex::from_str_bytes("hello, world!")).unwrap();
/// g.put(42, &Hex::from_str_bytes("hello, world!")).unwrap();
/// ```
///
/// # Errors
///
/// If vertex `v1` is absent, an `Err` will be returned.
pub fn put(&mut self, v: u32, d: Hex) -> Result<()> {
pub fn put(&mut self, v: u32, d: &Hex) -> Result<()> {
let vtx = self
.vertices
.get_mut(&v)
Expand Down Expand Up @@ -216,12 +216,9 @@ impl Sodg {
/// ```
///
/// If vertex `v1` is absent, `None` will be returned.
#[must_use]
pub fn kid(&self, v: u32, a: &str) -> Option<u32> {
if let Some(vtx) = self.vertices.get(&v) {
vtx.edges.iter().find(|e| e.a == a).map(|e| e.to)
} else {
None
}
self.vertices.get(&v).and_then(|vtx| vtx.edges.iter().find(|e| e.a == a).map(|e| e.to))
}
}

Expand Down Expand Up @@ -298,7 +295,7 @@ fn sets_simple_data() -> Result<()> {
let mut g = Sodg::empty();
let data = Hex::from_str_bytes("hello");
g.add(0)?;
g.put(0, data.clone())?;
g.put(0, &data)?;
assert_eq!(data, g.data(0)?);
Ok(())
}
Expand Down
10 changes: 3 additions & 7 deletions src/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,14 @@ impl Script {
/// assert_eq!(1, g.kid(0, "foo").unwrap());
/// ```
#[allow(clippy::should_implement_trait)]
#[must_use]
pub fn from_str(s: &str) -> Self {
Script {
Self {
txt: s.to_string(),
vars: HashMap::new(),
}
}

/// Make a new one, parsing a [`String`] with instructions.
pub fn from_string(s: String) -> Self {
Script::from_str(s.as_str())
}

/// Deploy the entire script to the [`Sodg`].
///
/// # Errors
Expand Down Expand Up @@ -146,7 +142,7 @@ impl Script {
"PUT" => {
let v = self.parse(args.get(0).context("V is expected")?, g)?;
let d = Self::parse_data(args.get(1).context("Data is expected")?)?;
g.put(v, d.clone())
g.put(v, &d)
.context(format!("Failed to PUT({v}, {d})"))
}
cmd => Err(anyhow!("Unknown command: {cmd}")),
Expand Down
4 changes: 2 additions & 2 deletions src/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ use crate::Hex;
fn saves_and_loads() -> Result<()> {
let mut g = Sodg::empty();
g.add(0)?;
g.put(0, Hex::from_str_bytes("hello"))?;
g.put(0, &Hex::from_str_bytes("hello"))?;
g.add(1)?;
g.bind(0, 1, "foo")?;
g.put(1, Hex::from_str_bytes("foo"))?;
g.put(1, &Hex::from_str_bytes("foo"))?;
let tmp = TempDir::new()?;
let file = tmp.path().join("foo.sodg");
g.save(file.as_path())?;
Expand Down
2 changes: 1 addition & 1 deletion src/xml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ use crate::Hex;
fn prints_simple_graph() -> Result<()> {
let mut g = Sodg::empty();
g.add(0)?;
g.put(0, Hex::from_str_bytes("hello"))?;
g.put(0, &Hex::from_str_bytes("hello"))?;
g.add(1)?;
g.bind(0, 1, "foo")?;
let xml = g.to_xml()?;
Expand Down

0 comments on commit 6c91fa8

Please sign in to comment.