diff --git a/.cargo/config.toml b/.cargo/config.toml deleted file mode 100644 index 2e07606d..00000000 --- a/.cargo/config.toml +++ /dev/null @@ -1,2 +0,0 @@ -[target.wasm32-unknown-unknown] -rustflags = ['--cfg', 'getrandom_backend="wasm_js"'] diff --git a/CHANGELOG.md b/CHANGELOG.md index ce7869a1..85f3faad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.13.5] - 2025-07-30 +## [0.13.5] - 2025-07-31 ### Fixed +- [[#346](https://github.com/plotly/plotly.rs/pull/346)] Remove usage of `getrandom` for `rand` dependency and for this crate - [[#345](https://github.com/plotly/plotly.rs/pull/345)] Re-export `ImageFormat` from `plotly_static` into `plotly` ## [0.13.4] - 2025-07-17 diff --git a/plotly/Cargo.toml b/plotly/Cargo.toml index f3400bb3..a744ceea 100644 --- a/plotly/Cargo.toml +++ b/plotly/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "plotly" -version = "0.13.4" +version = "0.13.5" description = "A plotting library powered by Plotly.js" authors = [ "Ioannis Giagkiozis ", @@ -60,10 +60,12 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_repr = "0.1" serde_with = ">=2, <4" -rand = "0.9" +rand = { version = "0.9", default-features = false, features = [ + "small_rng", + "alloc", +] } [target.'cfg(target_arch = "wasm32")'.dependencies] -getrandom = { version = "0.3", features = ["wasm_js"] } wasm-bindgen-futures = { version = "0.4" } wasm-bindgen = { version = "0.2" } serde-wasm-bindgen = { version = "0.6.3" } diff --git a/plotly/src/plot.rs b/plotly/src/plot.rs index 44b3b9db..130b75ea 100644 --- a/plotly/src/plot.rs +++ b/plotly/src/plot.rs @@ -1,3 +1,5 @@ +use std::sync::atomic::{AtomicU64, Ordering}; +use std::time::{SystemTime, UNIX_EPOCH}; use std::{fs::File, io::Write, path::Path}; use askama::Template; @@ -9,12 +11,15 @@ use plotly_kaleido::ImageFormat; use plotly_static::ImageFormat; use rand::{ distr::{Alphanumeric, SampleString}, - rng, + rngs::SmallRng, + SeedableRng, }; use serde::Serialize; use crate::{layout::Frame, Configuration, Layout}; +static SEED_COUNTER: AtomicU64 = AtomicU64::new(0); + #[derive(Template)] #[template(path = "plot.html", escape = "none")] struct PlotTemplate<'a> { @@ -265,12 +270,12 @@ impl Plot { #[cfg(all(not(target_family = "wasm"), not(target_os = "android")))] pub fn show(&self) { use std::env; - let rendered = self.render(); // Set up the temp file with a unique filename. let mut temp = env::temp_dir(); - let mut plot_name = Alphanumeric.sample_string(&mut rng(), 22); + let mut plot_name = + Alphanumeric.sample_string(&mut SmallRng::seed_from_u64(Self::generate_seed()), 22); plot_name.push_str(".html"); plot_name = format!("plotly_{plot_name}"); temp.push(plot_name); @@ -313,7 +318,8 @@ impl Plot { // Set up the temp file with a unique filename. let mut temp = env::temp_dir(); - let mut plot_name = Alphanumeric.sample_string(&mut rng(), 22); + let mut plot_name = + Alphanumeric.sample_string(&mut SmallRng::seed_from_u64(Self::generate_seed()), 22); plot_name.push_str(".html"); plot_name = format!("plotly_{plot_name}"); temp.push(plot_name); @@ -371,13 +377,16 @@ impl Plot { pub fn to_inline_html(&self, plot_div_id: Option<&str>) -> String { let plot_div_id = match plot_div_id { Some(id) => id.to_string(), - None => Alphanumeric.sample_string(&mut rng(), 20), + None => { + Alphanumeric.sample_string(&mut SmallRng::seed_from_u64(Self::generate_seed()), 20) + } }; self.render_inline(&plot_div_id) } fn to_jupyter_notebook_html(&self) -> String { - let plot_div_id = Alphanumeric.sample_string(&mut rng(), 20); + let plot_div_id = + Alphanumeric.sample_string(&mut SmallRng::seed_from_u64(Self::generate_seed()), 20); let tmpl = JupyterNotebookPlotTemplate { plot: self, @@ -869,6 +878,17 @@ impl Plot { .spawn() .expect(DEFAULT_HTML_APP_NOT_FOUND); } + + /// Generate unique seeds for SmallRng such that file names and div names + /// are unique random for each call + pub(crate) fn generate_seed() -> u64 { + let time = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or_default() + .as_nanos() as u64; + let counter = SEED_COUNTER.fetch_add(1, Ordering::Relaxed); + time ^ counter + } } impl PartialEq for Plot { diff --git a/plotly_derive/Cargo.toml b/plotly_derive/Cargo.toml index e4d8e4e6..159cc598 100644 --- a/plotly_derive/Cargo.toml +++ b/plotly_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "plotly_derive" -version = "0.13.4" +version = "0.13.5" description = "Internal proc macro crate for Plotly-rs." authors = ["Ioannis Giagkiozis "] license = "MIT" diff --git a/plotly_kaleido/Cargo.toml b/plotly_kaleido/Cargo.toml index d2d54c4e..65fb87e7 100644 --- a/plotly_kaleido/Cargo.toml +++ b/plotly_kaleido/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "plotly_kaleido" -version = "0.13.4" +version = "0.13.5" description = "Additional output format support for plotly using Kaleido" authors = [ "Ioannis Giagkiozis ",