Skip to content

Commit

Permalink
Fix text format
Browse files Browse the repository at this point in the history
  • Loading branch information
Kris030 committed Jul 31, 2023
1 parent 5cba3ae commit 8469f1d
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 159 deletions.
79 changes: 43 additions & 36 deletions client/examples/controller.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use roblib::cmd::Concrete;
use roblib::{cmd::Concrete, text_format};
use roblib_client::{
transports::{udp::Udp, Transport},
Result,
Expand All @@ -25,53 +25,60 @@ fn main() -> Result<()> {
"" => continue,
"exit" => break,
inp => {
let Ok(cmd) = roblib::text_format::de::from_str(inp) else {
let Ok(cmd) = text_format::de::from_str::<Concrete>(inp) else {
println!("Couldn't parse command");
continue;
};

println!("{}", text_format::ser::to_string(&cmd)?);

print!("< ");
match cmd {
Concrete::MoveRobot(c) => robot.cmd(c)?,
Concrete::MoveRobotByAngle(c) => robot.cmd(c)?,
Concrete::StopRobot(c) => robot.cmd(c)?,
Concrete::Led(c) => robot.cmd(c)?,
Concrete::RolandServo(c) => robot.cmd(c)?,
Concrete::Buzzer(c) => robot.cmd(c)?,
Concrete::TrackSensor(c) => println!("{:?}", robot.cmd(c)?),
Concrete::UltraSensor(c) => println!("{}", robot.cmd(c)?),
execute(cmd, &robot)?;
}
}
}

Ok(())
}

Concrete::PinMode(c) => robot.cmd(c)?,
Concrete::ReadPin(c) => println!("{}", robot.cmd(c)?),
Concrete::WritePin(c) => robot.cmd(c)?,
Concrete::Pwm(c) => robot.cmd(c)?,
Concrete::Servo(c) => robot.cmd(c)?,
fn execute(cmd: Concrete, robot: &impl Transport) -> Result<()> {
match cmd {
Concrete::MoveRobot(c) => robot.cmd(c)?,
Concrete::MoveRobotByAngle(c) => robot.cmd(c)?,
Concrete::StopRobot(c) => robot.cmd(c)?,
Concrete::Led(c) => robot.cmd(c)?,
Concrete::RolandServo(c) => robot.cmd(c)?,
Concrete::Buzzer(c) => robot.cmd(c)?,
Concrete::TrackSensor(c) => println!("{:?}", robot.cmd(c)?),
Concrete::UltraSensor(c) => println!("{}", robot.cmd(c)?),

Concrete::Subscribe(_) => {
println!("Subscribe no supported");
}
Concrete::Unsubscribe(_) => {
println!("Unsubscribe no supported");
}
Concrete::PinMode(c) => robot.cmd(c)?,
Concrete::ReadPin(c) => println!("{}", robot.cmd(c)?),
Concrete::WritePin(c) => robot.cmd(c)?,
Concrete::Pwm(c) => robot.cmd(c)?,
Concrete::Servo(c) => robot.cmd(c)?,

Concrete::Nop(c) => robot.cmd(c)?,
Concrete::GetUptime(c) => println!("{:?}", robot.cmd(c)?),
Concrete::Subscribe(_) => {
println!("Subscribe no supported");
}
Concrete::Unsubscribe(_) => {
println!("Unsubscribe no supported");
}

Concrete::GetPosition(c) => {
if let Some(p) = robot.cmd(c)? {
println!("{}", p)
} else {
println!("<")
}
}
Concrete::Nop(c) => robot.cmd(c)?,
Concrete::GetUptime(c) => println!("{:?}", robot.cmd(c)?),

Concrete::Abort(_) => {
println!("Abort no supported");
}
}
Concrete::GetPosition(c) => {
if let Some(p) = robot.cmd(c)? {
println!("{}", p)
} else {
println!("<")
}
}
}

Concrete::Abort(_) => {
println!("Abort no supported");
}
}
Ok(())
}
150 changes: 36 additions & 114 deletions roblib/src/cmd/concrete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ impl std::fmt::Debug for Concrete {
Self::TrackSensor(v) => v.fmt(f),
#[cfg(feature = "roland")]
Self::UltraSensor(v) => v.fmt(f),

#[cfg(feature = "gpio")]
Self::PinMode(v) => v.fmt(f),
#[cfg(feature = "gpio")]
Expand All @@ -74,8 +75,10 @@ impl std::fmt::Debug for Concrete {
Self::Pwm(v) => v.fmt(f),
#[cfg(feature = "gpio")]
Self::Servo(v) => v.fmt(f),

#[cfg(feature = "camloc")]
Self::GetPosition(v) => v.fmt(f),

Self::Subscribe(v) => v.fmt(f),
Self::Unsubscribe(v) => v.fmt(f),
Self::Nop(v) => v.fmt(f),
Expand Down Expand Up @@ -296,146 +299,65 @@ impl<'de> Deserialize<'de> for Concrete {
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;

Ok(match prefix {
match prefix {
#[cfg(feature = "roland")]
cmd::MoveRobot::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::MoveRobot(cmd)
}
cmd::MoveRobot::PREFIX => seq.next_element()?.map(Concrete::MoveRobot),

#[cfg(feature = "roland")]
cmd::MoveRobotByAngle::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::MoveRobotByAngle(cmd)
seq.next_element()?.map(Concrete::MoveRobotByAngle)
}

#[cfg(feature = "roland")]
cmd::StopRobot::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::StopRobot(cmd)
}
cmd::StopRobot::PREFIX => seq.next_element()?.map(Concrete::StopRobot),

#[cfg(feature = "roland")]
cmd::Led::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::Led(cmd)
}
cmd::Led::PREFIX => seq.next_element()?.map(Concrete::Led),

#[cfg(feature = "roland")]
cmd::RolandServo::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::RolandServo(cmd)
}
cmd::RolandServo::PREFIX => seq.next_element()?.map(Concrete::RolandServo),

#[cfg(feature = "roland")]
cmd::Buzzer::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::Buzzer(cmd)
}
cmd::Buzzer::PREFIX => seq.next_element()?.map(Concrete::Buzzer),

#[cfg(feature = "roland")]
cmd::TrackSensor::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::TrackSensor(cmd)
}
cmd::TrackSensor::PREFIX => seq.next_element()?.map(Concrete::TrackSensor),

#[cfg(feature = "roland")]
cmd::UltraSensor::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::UltraSensor(cmd)
}
cmd::UltraSensor::PREFIX => seq.next_element()?.map(Concrete::UltraSensor),

#[cfg(feature = "gpio")]
cmd::PinMode::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::PinMode(cmd)
}
cmd::PinMode::PREFIX => seq.next_element()?.map(Concrete::PinMode),

#[cfg(feature = "gpio")]
cmd::ReadPin::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::ReadPin(cmd)
}
cmd::ReadPin::PREFIX => seq.next_element()?.map(Concrete::ReadPin),

#[cfg(feature = "gpio")]
cmd::WritePin::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::WritePin(cmd)
}
cmd::WritePin::PREFIX => seq.next_element()?.map(Concrete::WritePin),

#[cfg(feature = "gpio")]
cmd::Pwm::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::Pwm(cmd)
}
cmd::Pwm::PREFIX => seq.next_element()?.map(Concrete::Pwm),

#[cfg(feature = "gpio")]
cmd::Servo::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::Servo(cmd)
}
cmd::Servo::PREFIX => seq.next_element()?.map(Concrete::Servo),

#[cfg(feature = "camloc")]
cmd::GetPosition::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::GetPosition(cmd)
}
cmd::GetPosition::PREFIX => seq.next_element()?.map(Concrete::GetPosition),

cmd::Subscribe::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::Subscribe(cmd)
}
cmd::Unsubscribe::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::Unsubscribe(cmd)
}
cmd::Nop::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::Nop(cmd)
}
cmd::GetUptime::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::GetUptime(cmd)
}
cmd::Abort::PREFIX => {
let cmd = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
Concrete::Abort(cmd)
}
cmd::Subscribe::PREFIX => seq.next_element()?.map(Concrete::Subscribe),
cmd::Unsubscribe::PREFIX => seq.next_element()?.map(Concrete::Unsubscribe),
cmd::Nop::PREFIX => seq.next_element()?.map(Concrete::Nop),
cmd::GetUptime::PREFIX => seq.next_element()?.map(Concrete::GetUptime),
cmd::Abort::PREFIX => seq.next_element()?.map(Concrete::Abort),

_ => {
return Err(de::Error::invalid_value(
de::Unexpected::Char(prefix),
&"a command prefix",
))
}
})
}
.ok_or_else(|| de::Error::invalid_length(0, &self))
}
}

Expand Down
18 changes: 14 additions & 4 deletions roblib/src/text_format/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ where

impl<'de, I: Iterator<Item = &'de str>> Deserializer<I> {
fn next(&mut self) -> Result<I::Item> {
match self.iter.next() {
let v = self.iter.next();
match v {
Some("") => Err(Error::Empty),
Some(s) => Ok(s),
None => Err(Error::MissingArgument),
Expand Down Expand Up @@ -222,11 +223,19 @@ impl<'de, 'a, I: Iterator<Item = &'de str>> de::Deserializer<'de> for &'a mut De
self.deserialize_seq(visitor)
}

fn deserialize_tuple_struct<V>(self, _: &'static str, _: usize, visitor: V) -> Result<V::Value>
fn deserialize_tuple_struct<V>(
self,
_: &'static str,
fields: usize,
visitor: V,
) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_seq(visitor)
visitor.visit_seq(Seq {
de: self,
left: fields as u32,
})
}

fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
Expand Down Expand Up @@ -297,7 +306,8 @@ impl<'de, 'a, I: Iterator<Item = &'de str>> SeqAccess<'de> for Seq<'de, 'a, I> {
if self.left > 0 {
self.left -= 1;

seed.deserialize(&mut *self.de).map(Some)
let r = seed.deserialize(&mut *self.de);
r.map(Some)
} else {
Ok(None)
}
Expand Down
34 changes: 29 additions & 5 deletions roblib/src/text_format/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,50 @@ use serde::{
};
use std::fmt::{self, Write};

pub fn to_string(s: &impl Serialize) -> Result<String> {
let mut r = String::new();
s.serialize(&mut Serializer::new(&mut r))?;
Ok(r)
}

pub struct Serializer<W: fmt::Write> {
first: bool,
formatting: bool,
put_separator: bool,
writer: W,
}

impl<W: fmt::Write> Serializer<W> {
pub fn new(writer: W) -> Self {
Self {
first: true,
put_separator: false,
formatting: false,
writer,
}
}
}

impl<W: fmt::Write> fmt::Write for Serializer<W> {
fn write_str(&mut self, s: &str) -> fmt::Result {
if !self.first {
self.writer.write_fmt(format_args!("{}", SEPARATOR))?;
if self.put_separator {
if self.formatting {
self.put_separator = false;
}
self.writer.write_fmt(format_args!("{}{s}", SEPARATOR))
} else {
if !self.formatting {
self.put_separator = true;
}
self.writer.write_str(s)
}
self.writer.write_str(s)
}

fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result {
self.put_separator = true;
self.formatting = true;
fmt::write(self, args)?;
self.formatting = false;
self.put_separator = true;
Ok(())
}
}

Expand Down

1 comment on commit 8469f1d

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Artifacts

View all

base roland
aarch64-unknown-linux-gnu Download Download
aarch64-unknown-linux-musl Download Download
armv7-unknown-linux-gnueabihf Download Download
armv7-unknown-linux-musleabihf Download Download
x86_64-pc-windows-msvc Download Download
x86_64-unknown-linux-gnu Download Download
x86_64-unknown-linux-musl Download Download

Please sign in to comment.