Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
softprops committed Dec 18, 2018
1 parent 08bc1ba commit 9fa3349
Show file tree
Hide file tree
Showing 6 changed files with 281 additions and 130 deletions.
77 changes: 77 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# required because of tarpaulin dependency
sudo: required

language: rust

matrix:
fast_finish: true
include:
- rust: nightly
- rust: beta
- rust: stable
allow_failures:
- rust: nightly

# only build pushes to master
# prs are build separately
# https://docs.travis-ci.com/user/pull-requests/#how-pull-requests-are-built
branches:
only:
- master

install: |
# see https://github.com/xd009642/tarpaulin/issues/150 for tarpaulin nightly dependency
if [[ "$TRAVIS_RUST_VERSION" == nightly ]]; then
`RUSTFLAGS="--cfg procmacro2_semver_exempt" cargo install cargo-tarpaulin -f`
# should only be necessary until rustfmt produces consistent results in stable/nightly
rustup component add rustfmt
fi
script:
- |
if [[ "$TRAVIS_RUST_VERSION" == nightly ]]; then
cargo fmt --all -- --check
fi
- cargo test

# Cache `cargo install`ed tools, but don't cache the project's `target`
# directory (which ends up over-caching and filling all disk space!)
# https://levans.fr/rust_travis_cache.html
cache:
directories:
- /home/travis/.cargo

before_cache:
# But don't cache the cargo registry
- rm -rf /home/travis/.cargo/registry
# Travis can't cache files that are not readable by "others"
- chmod -R a+r $HOME/.cargo

addons:
apt:
packages:
# required by tarpaulin code coverage tool
- libssl-dev

after_success:
# report coverage to coveralls
# see https://github.com/xd009642/tarpaulin for more information
- '[ $TRAVIS_RUST_VERSION = nightly ] &&
[ $TRAVIS_BRANCH = master ] &&
[ $TRAVIS_PULL_REQUEST = false ] &&
cargo +nightly tarpaulin --ciserver travis-ci --coveralls $TRAVIS_JOB_ID || true'
- '[ $TRAVIS_RUST_VERSION = stable ] &&
[ $TRAVIS_BRANCH = master ] &&
[ $TRAVIS_PULL_REQUEST = false ]
&& cargo doc --no-deps &&
echo "<meta http-equiv=refresh content=0;url=`echo $TRAVIS_REPO_SLUG | cut -d / -f 2`/index.html>" > target/doc/index.html'

deploy:
provider: pages
skip-cleanup: true
github-token: $GH_TOKEN
local-dir: target/doc
keep-history: false
on:
branch: master
condition: $TRAVIS_RUST_VERSION = stable
113 changes: 113 additions & 0 deletions src/epoch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
use serde::{de, ser, Serializer};
use std::{
fmt,
time::{Duration, SystemTime, UNIX_EPOCH},
};

/// Represents fractional seconds since the epoch
/// These can be derived from std::time::Duration and be converted
/// too std::time::Duration
///
/// A Default implementation is provided which yields the number of seconds since the epoch from
/// the system time's `now` value
#[derive(Debug, PartialEq)]
pub struct Seconds(pub(crate) f64);

impl Seconds {
/// return the current time in seconds since the unix epoch (1-1-1970 midnight)
pub fn now() -> Self {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.into()
}

/// truncate epoc time to remove fractional seconds
pub fn trunc(&self) -> u64 {
self.0.trunc() as u64
}
}

impl Default for Seconds {
fn default() -> Self {
Seconds::now()
}
}

impl From<Duration> for Seconds {
fn from(d: Duration) -> Self {
Seconds(d.as_secs() as f64 + (f64::from(d.subsec_nanos()) / 1.0e9))
}
}

impl Into<Duration> for Seconds {
fn into(self) -> Duration {
let Seconds(secs) = self;
Duration::new(secs.trunc() as u64, (secs.fract() * 1.0e9) as u32)
}
}

struct SecondsVisitor;

impl<'de> de::Visitor<'de> for SecondsVisitor {
type Value = Seconds;

fn expecting(
&self,
formatter: &mut fmt::Formatter,
) -> fmt::Result {
formatter.write_str("a string value")
}
fn visit_f64<E>(
self,
value: f64,
) -> Result<Seconds, E>
where
E: de::Error,
{
Ok(Seconds(value))
}
}

impl ser::Serialize for Seconds {
fn serialize<S>(
&self,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let Seconds(seconds) = self;
serializer.serialize_f64(*seconds)
}
}

impl<'de> de::Deserialize<'de> for Seconds {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
deserializer.deserialize_f64(SecondsVisitor)
}
}

#[cfg(test)]
mod tests {
use super::Seconds;

#[test]
fn seconds_serialize() {
assert_eq!(
serde_json::to_string(&Seconds(1_545_136_342.711_932)).expect("failed to serialize"),
"1545136342.711932"
);
}

#[test]
fn seconds_deserialize() {
assert_eq!(
serde_json::from_slice::<Seconds>(b"1545136342.711932").expect("failed to serialize"),
Seconds(1_545_136_342.711_932)
);
}
}
84 changes: 0 additions & 84 deletions src/epoch_seconds.rs

This file was deleted.

Loading

0 comments on commit 9fa3349

Please sign in to comment.