diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 66b5ca78..92646550 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,9 +72,6 @@ jobs: - run: cargo hack build --workspace --feature-powerset # When this job failed, run ci/no_atomic.sh and commit result changes. - # TODO(taiki-e): Ideally, this should be automated using a bot that creates - # PR when failed, but there is no bandwidth to implement it - # right now... codegen: runs-on: ubuntu-latest steps: @@ -82,7 +79,30 @@ jobs: - name: Install Rust run: rustup update nightly && rustup default nightly - run: ci/no_atomic.sh - - run: git diff --exit-code + - run: git add -N . && git diff --exit-code + if: github.repository_owner != 'tokio-rs' || github.event_name != 'schedule' + - id: diff + run: | + git config user.name "Taiki Endo" + git config user.email "te316e89@gmail.com" + git add -N . + if ! git diff --exit-code; then + git add . + git commit -m "Update no_atomic.rs" + echo "::set-output name=success::false" + fi + if: github.repository_owner == 'tokio-rs' && github.event_name == 'schedule' + - uses: peter-evans/create-pull-request@v3 + with: + title: Update no_atomic.rs + body: | + Auto-generated by [create-pull-request][1] + [Please close and immediately reopen this pull request to run CI.][2] + + [1]: https://github.com/peter-evans/create-pull-request + [2]: https://github.com/peter-evans/create-pull-request/blob/HEAD/docs/concepts-guidelines.md#workarounds-to-trigger-further-workflow-runs + branch: update-no-atomic-rs + if: github.repository_owner == 'tokio-rs' && github.event_name == 'schedule' && steps.diff.outputs.success == 'false' fmt: runs-on: ubuntu-latest diff --git a/valuable-serde/src/lib.rs b/valuable-serde/src/lib.rs index 73d53d46..480be1f7 100644 --- a/valuable-serde/src/lib.rs +++ b/valuable-serde/src/lib.rs @@ -265,6 +265,7 @@ where Value::Path(p) => Serialize::serialize(p, serializer), #[cfg(feature = "std")] Value::Error(e) => Err(S::Error::custom(e)), + Value::Display(d) => serializer.collect_str(d), v => unimplemented!("{:?}", v), } diff --git a/valuable/no_atomic.rs b/valuable/no_atomic.rs index 3c251556..6594d628 100644 --- a/valuable/no_atomic.rs +++ b/valuable/no_atomic.rs @@ -43,7 +43,6 @@ const NO_ATOMIC_64: &[&str] = &[ "riscv32gc-unknown-linux-gnu", "riscv32gc-unknown-linux-musl", "riscv32imac-unknown-none-elf", - "riscv32imc-esp-espidf", "thumbv7em-none-eabi", "thumbv7em-none-eabihf", "thumbv7m-none-eabi", diff --git a/valuable/src/value.rs b/valuable/src/value.rs index d1552875..d1dafaff 100644 --- a/valuable/src/value.rs +++ b/valuable/src/value.rs @@ -113,6 +113,12 @@ macro_rules! value { } } + impl<'a> From<&'a dyn fmt::Display> for Value<'a> { + fn from(src: &'a dyn fmt::Display) -> Self { + Self::Display(src) + } + } + impl fmt::Debug for Value<'_> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { use Value::*; @@ -125,7 +131,7 @@ macro_rules! value { $(#[$attrs])* $variant(v) => fmt::Debug::fmt(v, fmt), )* - Display(d) => d.fmt(fmt), + Display(d) => write!(fmt, "\"{}\"", d), Unit => ().fmt(fmt), } } @@ -715,6 +721,12 @@ macro_rules! convert { /// Return a `&dyn Display` representation of `self`, if possible. /// + /// If this value is a [`Value::Display`] variant, or any primitive + /// `Value` variant, this method will return a `&dyn Display` trait + /// object. Otherwise, if the value is [`Structable`], + /// [`Enumerable`], [`Tupleable`], [`Listable`], [`Mappable`], or a + /// [`Value::Path`], this method will return `None`. + /// /// # Examples /// /// ``` @@ -732,11 +744,40 @@ macro_rules! convert { /// let meters = Meters(5); /// /// assert!(Value::Display(&meters).as_display().is_some()); - /// assert!(Value::Bool(true).as_display().is_none()); + /// assert!(Value::Tupleable((true, "hello")).as_display().is_none()); /// ``` pub fn as_display(&self) -> Option<&dyn fmt::Display> { + use Value::*; match *self { - Value::Display(v) => Some(v), + I8(ref v) => Some(v), + I16(ref v) => Some(v), + I32(ref v) => Some(v), + I64(ref v) => Some(v), + I128(ref v) => Some(v), + Isize(ref v) => Some(v), + U8(ref v) => Some(v), + U16(ref v) => Some(v), + U32(ref v) => Some(v), + U64(ref v) => Some(v), + U128(ref v) => Some(v), + Usize(ref v) => Some(v), + F32(ref v) => Some(v), + F64(ref v) => Some(v), + Bool(ref v) => Some(v), + Char(ref v) => Some(v), + String(ref v) => Some(v), + + #[cfg(feature = "std")] + Error(ref v) => Some(v), + + // XXX(eliza): this, sadly, does not work for `Path`s; the + // only way to return them as a `Display` impl is + // `Path::display`, which creates a value owned by _this_ + // function; we can't return that as a trait object because + // we're borrowing it from the function's scope rather than + // from the value itself. + + Display(v) => Some(v), _ => None, } }