summaryrefslogtreecommitdiffstats
path: root/src/version.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/version.rs')
-rw-r--r--src/version.rs65
1 files changed, 57 insertions, 8 deletions
diff --git a/src/version.rs b/src/version.rs
index 6354143..462ba3b 100644
--- a/src/version.rs
+++ b/src/version.rs
@@ -1,10 +1,12 @@
use core::fmt;
use std::{collections::BTreeMap, convert::Infallible, marker::PhantomData, ops::Deref, str::FromStr};
use std::collections::HashMap;
-use chrono::{DateTime, Utc};
+use chrono::{DateTime, NaiveDateTime, Utc};
+use chrono::format::ParseErrorKind;
+use indexmap::IndexMap;
use regex::Regex;
use serde::{de::{self, Visitor}, Deserialize, Deserializer};
-use serde::de::SeqAccess;
+use serde::de::{Error, SeqAccess};
use sha1_smol::Digest;
pub mod manifest;
@@ -203,7 +205,17 @@ pub struct Library {
pub extract: Option<LibraryExtractRule>,
pub natives: Option<BTreeMap<OperatingSystem, String>>,
pub rules: Option<Vec<CompatibilityRule>>,
- pub url: Option<String> // old format
+
+ // old format
+ pub url: Option<String>,
+ pub size: Option<usize>,
+ pub sha1: Option<Digest>
+}
+
+impl Library {
+ pub fn get_canonical_name(&self) -> String {
+ canonicalize_library_name(self.name.as_str())
+ }
}
impl LibraryDownloads {
@@ -227,7 +239,7 @@ pub struct ClientLogging {
#[derive(Deserialize, Debug, Clone)]
pub struct Logging {
- pub client: ClientLogging // other fields unknown
+ pub client: Option<ClientLogging> // other fields unknown
}
#[derive(Deserialize, Debug, Clone)]
@@ -247,7 +259,7 @@ pub struct CompleteVersion {
pub downloads: BTreeMap<DownloadType, DownloadInfo>,
#[serde(default, deserialize_with = "deserialize_libraries")]
- pub libraries: HashMap<String, Library>,
+ pub libraries: IndexMap<String, Library>,
pub id: String,
pub jar: Option<String>, // used as the jar filename if specified? (no longer used officially)
@@ -256,7 +268,10 @@ pub struct CompleteVersion {
pub main_class: Option<String>,
pub minimum_launcher_version: Option<u32>,
+
+ #[serde(deserialize_with = "deserialize_datetime_lenient")]
pub release_time: Option<DateTime<Utc>>,
+ #[serde(deserialize_with = "deserialize_datetime_lenient")]
pub time: Option<DateTime<Utc>>,
#[serde(rename = "type")]
@@ -338,14 +353,48 @@ fn canonicalize_library_name(name: &str) -> String {
.join(":")
}
-fn deserialize_libraries<'de, D>(deserializer: D) -> Result<HashMap<String, Library>, D::Error>
+fn deserialize_datetime_lenient<'de, D>(deserializer: D) -> Result<Option<DateTime<Utc>>, D::Error>
+where
+ D: Deserializer<'de>
+{
+ struct DateTimeVisitor;
+
+ impl<'de> Visitor<'de> for DateTimeVisitor {
+ type Value = Option<DateTime<Utc>>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a valid datetime")
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+ where
+ E: Error
+ {
+ match value.parse::<DateTime<Utc>>() {
+ Ok(dt) => Ok(Some(dt)),
+ Err(e) if e.kind() == ParseErrorKind::TooShort => {
+ // this probably just doesn't have an offset for some reason
+ match value.parse::<NaiveDateTime>() {
+ Ok(ndt) => Ok(Some(ndt.and_utc())),
+ Err(e) => Err(Error::custom(e))
+ }
+ },
+ Err(e) => Err(Error::custom(e))
+ }
+ }
+ }
+
+ deserializer.deserialize_str(DateTimeVisitor)
+}
+
+fn deserialize_libraries<'de, D>(deserializer: D) -> Result<IndexMap<String, Library>, D::Error>
where
D: Deserializer<'de>
{
struct LibrariesVisitor;
impl<'de> Visitor<'de> for LibrariesVisitor {
- type Value = HashMap<String, Library>;
+ type Value = IndexMap<String, Library>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an array of libraries")
@@ -355,7 +404,7 @@ where
where
A: SeqAccess<'de>,
{
- let mut map = HashMap::new();
+ let mut map = IndexMap::new();
while let Some(lib) = seq.next_element::<Library>()? {
//map.insert(canonicalize_library_name(lib.name.as_str()), lib);