Skip to content

Commit 9b0307b

Browse files
committed
feat: read unknown versions
1 parent a48432d commit 9b0307b

File tree

13 files changed

+43
-39
lines changed

13 files changed

+43
-39
lines changed

cli/src/args/migrate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ impl Run for Args {
2121
async fn run(self, input: Input, _: Option<Sender<Value>>) -> Result<Option<Value>> {
2222
let value = input.get().await?;
2323
value
24-
.migrate(self.version)
24+
.migrate(&self.version)
2525
.map(Value::from)
2626
.map(Some)
2727
.map_err(Error::from)

cli/src/args/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ impl Args {
133133
)?;
134134
let mut output = Output::new(
135135
self.subcommand.take_outfile(),
136-
self.output_format.or_else(|| {
136+
self.output_format.or({
137137
if self.stream {
138138
Some(crate::output::Format::NdJson)
139139
} else {

cli/src/input.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl Input {
5252

5353
/// Creates a new input with the given href.
5454
pub(crate) fn with_href(&self, href: &str) -> Result<Input> {
55-
let (object_store, path) = parse_href_opts(&href, self.config.iter())?;
55+
let (object_store, path) = parse_href_opts(href, self.config.iter())?;
5656
let reader = Reader::ObjectStore { object_store, path };
5757
Ok(Input {
5858
format: self.format,
@@ -66,7 +66,7 @@ impl Input {
6666
tracing::debug!("getting {}", self.format);
6767
match &self.reader {
6868
Reader::ObjectStore { object_store, path } => {
69-
let bytes = object_store.get(&path).await?.bytes().await?;
69+
let bytes = object_store.get(path).await?.bytes().await?;
7070
match self.format {
7171
Format::Json => serde_json::from_slice(&bytes).map_err(Error::from),
7272
Format::NdJson => bytes
@@ -110,7 +110,7 @@ where
110110
K: AsRef<str>,
111111
V: Into<String>,
112112
{
113-
if let Some(url) = Url::parse(href).ok() {
113+
if let Ok(url) = Url::parse(href) {
114114
object_store::parse_url_opts(&url, options).map_err(Error::from)
115115
} else {
116116
let path = Path::from_filesystem_path(href)?;

cli/src/output.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ impl Output {
103103
let bytes = value.into_bytes(self.format)?;
104104
if let Some((object_store, path)) = &self.writer.object_store {
105105
object_store
106-
.put(path, PutPayload::from_bytes(bytes.into()))
106+
.put(path, PutPayload::from_bytes(bytes))
107107
.await
108108
.map(Some)
109109
.map_err(Error::from)

core/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
1111
- Deref `ItemCollection` ([#363](https://github.com/stac-utils/stac-rs/pull/363))
1212
- `object_store` and `ndjson` ([#369](https://github.com/stac-utils/stac-rs/pull/369))
1313
- `Format` ([#372](https://github.com/stac-utils/stac-rs/pull/371))
14+
- Read unknown versions ([#378](https://github.com/stac-utils/stac-rs/pull/378))
1415

1516
### Changed
1617

core/src/item_collection.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ where
109109
}
110110

111111
impl Migrate for ItemCollection {
112-
fn migrate(mut self, version: crate::Version) -> crate::Result<Self> {
112+
fn migrate(mut self, version: &crate::Version) -> crate::Result<Self> {
113113
let mut items = Vec::with_capacity(self.items.len());
114114
for item in self.items {
115115
items.push(item.migrate(version)?);

core/src/migrate.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
use std::collections::HashMap;
2-
31
use crate::{Error, Result, Version};
42
use serde::{de::DeserializeOwned, Serialize};
53
use serde_json::{Map, Value};
4+
use std::collections::HashMap;
65

76
/// Migrates a STAC object from one version to another.
8-
pub trait Migrate: Sized + Serialize + DeserializeOwned {
7+
pub trait Migrate: Sized + Serialize + DeserializeOwned + std::fmt::Debug {
98
/// Migrates this object to another version.
109
///
1110
/// # Examples
@@ -14,17 +13,17 @@ pub trait Migrate: Sized + Serialize + DeserializeOwned {
1413
/// use stac::{Item, Migrate, Version};
1514
///
1615
/// let mut item: Item = stac::read("../spec-examples/v1.0.0/simple-item.json").unwrap();
17-
/// let item = item.migrate(Version::v1_1_0_beta_1).unwrap();
16+
/// let item = item.migrate(&Version::v1_1_0_beta_1).unwrap();
1817
/// assert_eq!(item.version, Version::v1_1_0_beta_1);
1918
/// ```
20-
fn migrate(self, to: Version) -> Result<Self> {
19+
fn migrate(self, to: &Version) -> Result<Self> {
2120
let mut value = serde_json::to_value(self)?;
2221
if let Some(version) = value
2322
.as_object()
2423
.and_then(|object| object.get("stac_version"))
2524
.and_then(|version| version.as_str())
2625
{
27-
let from: Version = version.parse()?;
26+
let from: Version = version.parse().unwrap(); // infallible
2827
let steps = from.steps(to)?;
2928
for step in steps {
3029
value = step.migrate(value)?;
@@ -46,16 +45,18 @@ enum Step {
4645
}
4746

4847
impl Version {
49-
fn steps(self, to: Version) -> Result<Vec<Step>> {
48+
fn steps(self, to: &Version) -> Result<Vec<Step>> {
5049
match self {
5150
Version::v1_0_0 => match to {
5251
Version::v1_0_0 => Ok(Vec::new()),
5352
Version::v1_1_0_beta_1 => Ok(vec![Step::v1_0_0_to_v1_1_0_beta_1]),
53+
_ => Err(Error::UnsupportedMigration(self, to.clone())),
5454
},
5555
Version::v1_1_0_beta_1 => match to {
56-
Version::v1_0_0 => Err(Error::UnsupportedMigration(self, to)),
5756
Version::v1_1_0_beta_1 => Ok(Vec::new()),
57+
_ => Err(Error::UnsupportedMigration(self, to.clone())),
5858
},
59+
Version::Unknown(_) => Err(Error::UnsupportedMigration(self, to.clone())),
5960
}
6061
}
6162
}
@@ -215,7 +216,7 @@ mod tests {
215216
#[test]
216217
fn migrate_v1_0_0_to_v1_1_0_beta_1() {
217218
let item: Item = crate::read("data/bands-v1.0.0.json").unwrap();
218-
let item = item.migrate(Version::v1_1_0_beta_1).unwrap();
219+
let item = item.migrate(&Version::v1_1_0_beta_1).unwrap();
219220
let asset = &item.assets["example"];
220221
assert_eq!(asset.data_type.as_ref().unwrap(), &DataType::UInt16);
221222
assert_eq!(asset.bands[0].name.as_ref().unwrap(), "r");
@@ -229,20 +230,20 @@ mod tests {
229230
assert_json_eq!(expected, serde_json::to_value(item).unwrap());
230231

231232
let collection = Collection::new("an-id", "a description");
232-
let collection = collection.migrate(Version::v1_1_0_beta_1).unwrap();
233+
let collection = collection.migrate(&Version::v1_1_0_beta_1).unwrap();
233234
assert_eq!(collection.license, "other");
234235

235236
let mut item = Item::new("an-id");
236237
item.set_link(Link::self_("/an/absolute/href"));
237-
let item = item.migrate(Version::v1_1_0_beta_1).unwrap();
238+
let item = item.migrate(&Version::v1_1_0_beta_1).unwrap();
238239
assert_eq!(item.link("self").unwrap().href, "file:///an/absolute/href");
239240
}
240241

241242
#[test]
242243
fn remove_empty_bands() {
243244
// https://github.com/stac-utils/stac-rs/issues/350
244245
let item: Item = crate::read("data/20201211_223832_CS2.json").unwrap();
245-
let item = item.migrate(Version::v1_1_0_beta_1).unwrap();
246+
let item = item.migrate(&Version::v1_1_0_beta_1).unwrap();
246247
let asset = &item.assets["data"];
247248
assert!(asset.bands.is_empty());
248249
}

core/src/value.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ impl From<ItemCollection> for Value {
274274
}
275275

276276
impl Migrate for Value {
277-
fn migrate(self, version: Version) -> Result<Value> {
277+
fn migrate(self, version: &Version) -> Result<Value> {
278278
match self {
279279
Value::Item(item) => item.migrate(version).map(Value::Item),
280280
Value::Catalog(catalog) => catalog.migrate(version).map(Value::Catalog),

core/src/version.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use crate::Error;
21
use serde::{Deserialize, Serialize};
3-
use std::{fmt::Display, str::FromStr};
2+
use std::{convert::Infallible, fmt::Display, str::FromStr};
43

54
/// A version of the STAC specification.
6-
#[derive(Default, Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Eq, Hash, PartialOrd)]
5+
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Eq, Hash, PartialOrd)]
76
#[allow(non_camel_case_types)]
7+
#[non_exhaustive]
88
pub enum Version {
99
/// [v1.0.0](https://github.com/radiantearth/stac-spec/releases/tag/v1.0.0)
1010
#[default]
@@ -14,16 +14,20 @@ pub enum Version {
1414
/// [v1.1.0-beta.1](https://github.com/radiantearth/stac-spec/releases/tag/v1.1.0-beta.1)
1515
#[serde(rename = "1.1.0-beta.1")]
1616
v1_1_0_beta_1,
17+
18+
/// An unknown STAC version.
19+
#[serde(untagged)]
20+
Unknown(String),
1721
}
1822

1923
impl FromStr for Version {
20-
type Err = Error;
24+
type Err = Infallible;
2125

2226
fn from_str(s: &str) -> Result<Self, Self::Err> {
2327
match s {
2428
"1.0.0" => Ok(Version::v1_0_0),
2529
"1.1.0-beta.1" => Ok(Version::v1_1_0_beta_1),
26-
_ => Err(Error::UnsupportedVersion(s.to_string())),
30+
_ => Ok(Version::Unknown(s.to_string())),
2731
}
2832
}
2933
}
@@ -36,6 +40,7 @@ impl Display for Version {
3640
match self {
3741
Version::v1_0_0 => "1.0.0",
3842
Version::v1_1_0_beta_1 => "1.1.0-beta.1",
43+
Version::Unknown(v) => v,
3944
}
4045
)
4146
}

core/tests/migrate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ use std::path::PathBuf;
55
#[rstest]
66
fn v1_0_0_to_v1_1_0_beta_1(#[files("../spec-examples/v1.0.0/**/*.json")] path: PathBuf) {
77
let value: Value = stac::read(path.to_str().unwrap()).unwrap();
8-
let _ = value.migrate(Version::v1_1_0_beta_1).unwrap();
8+
let _ = value.migrate(&Version::v1_1_0_beta_1).unwrap();
99
}

0 commit comments

Comments
 (0)