Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 Fix error propagation from rust to python #3

Merged
merged 5 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 185 additions & 0 deletions python_genshin_artifact/tests/input/invalid_enka_name.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
{
"character": {
"name": "HuTao",
"level": 81,
"ascend": false,
"constellation": 1,
"skill1": 9,
"skill2": 8,
"skill3": 7,
"params": {
"HuTao": {
"le_50": true
}
}
},
"weapon": {
"name": "DragonSBane",
"level": 90,
"ascend": false,
"refine": 4,
"params": "NoConfig"
},
"buffs": [],
"artifacts": [
{
"set_name": "WandererSTroupe",
"slot": "Flower",
"level": 20,
"star": 5,
"sub_stats": [
[
"CriticalRate",
0.14800000000000002
],
[
"Recharge",
5.8
],
[
"HPPercentage",
0.111
],
[
"CriticalDamage",
0.14800000000000002
]
],
"main_stat": [
"HPFixed",
4780.0
],
"id": 15003
},
{
"set_name": "CrimsonWitchOfFlames",
"slot": "Feather",
"level": 20,
"star": 5,
"sub_stats": [
[
"CriticalRate",
0.113
],
[
"ATKPercentage",
0.099
],
[
"CriticalDamage",
0.132
],
[
"DEFFixed",
19.0
]
],
"main_stat": [
"ATKFixed",
311.0
],
"id": 15006
},
{
"set_name": "CrimsonWitchOfFlames",
"slot": "Sand",
"level": 20,
"star": 5,
"sub_stats": [
[
"DEFPercentage",
0.11699999999999999
],
[
"CriticalRate",
0.039
],
[
"CriticalDamage",
0.19399999999999998
],
[
"Recharge",
14.9
]
],
"main_stat": [
"HPPercentage",
0.466
],
"id": 15006
},
{
"set_name": "EmblemOfSeveredFate",
"slot": "Goblet",
"level": 20,
"star": 5,
"sub_stats": [
[
"DEFFixed",
21.0
],
[
"CriticalDamage",
0.225
],
[
"HPFixed",
209.0
],
[
"CriticalRate",
0.113
]
],
"main_stat": [
"PyroBonus",
0.466
],
"id": 15020
},
{
"set_name": "WandererSTroupe",
"slot": "Head",
"level": 20,
"star": 5,
"sub_stats": [
[
"HPPercentage",
0.122
],
[
"DEFFixed",
21.0
],
[
"CriticalDamage",
0.21
],
[
"HPFixed",
418.0
]
],
"main_stat": [
"CriticalRate",
0.311
],
"id": 15003
}
],
"artifact_config": {
"config_crimson_witch_of_flames": {
"level": 1
}
},
"skill": {
"index": 7,
"config": {
"HuTao": {
"after_e": true
}
}
},
"enemy": null
}
18 changes: 18 additions & 0 deletions python_genshin_artifact/tests/test_damage_calculator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import json
from json import JSONDecodeError
from pathlib import Path

import pytest
from python_genshin_artifact.calculator import get_damage_analysis
from python_genshin_artifact.models.calculator import CalculatorConfig


TEST_DATA_DIR = Path(__file__).resolve().parent / "input"


def test_damage_analysis_exception():
"""Test damage analysis raises expected exception on invalid input"""
with open(TEST_DATA_DIR / "invalid_enka_name.json") as f:
config = CalculatorConfig(**json.load(f))
with pytest.raises(JSONDecodeError, match="unknown variant"):
get_damage_analysis(config)
5 changes: 3 additions & 2 deletions python_genshin_artifact_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ name = "genshin_artifact_core"
crate-type = ["cdylib"]

[dependencies]
pyo3 = { version = "0.19.2", features = ["extension-module"] }
pyo3 = { version = "0.19.2", features = ["extension-module", "anyhow"] }
mona_wasm = { path = "../genshin_artifact/mona_wasm" }
mona = { path = "../genshin_artifact/mona_core" }
mona_generate = { path = "../genshin_artifact/mona_generate" }
num = "0.4"
serde="1.0"
serde_json = "1.0"
serde_json = "1.0"
anyhow = "1.0.75"
3 changes: 3 additions & 0 deletions python_genshin_artifact_core/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[toolchain]
channel = "nightly"
components = [ "rustfmt", "clippy" ]
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use anyhow::Context;
use mona::artifacts::artifact_trait::ArtifactMetaData;
use mona::artifacts::ArtifactSetName;
use mona::common::item_config_type::ItemConfig;
Expand Down Expand Up @@ -132,6 +133,6 @@ pub fn gen_artifact_meta_as_json() -> PyResult<String> {
})
}

let result_str = serde_json::to_string(&data).unwrap();
let result_str = serde_json::to_string(&data).context("Failed to serialize json")?;
Ok(result_str)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use mona_generate::gen_meta::gen_locale::generate_locale_vec;
use pyo3::prelude::*;

#[pyfunction]
pub fn gen_generate_locale_as_json(loc: String)-> PyResult<String> {
pub fn gen_generate_locale_as_json(loc: String) -> PyResult<String> {
let json = serde_json::to_string_pretty(&generate_locale_vec(&loc)).unwrap();
Ok(json)
}
}
4 changes: 2 additions & 2 deletions python_genshin_artifact_core/src/applications/generate/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub mod artifact;
pub mod character;
pub mod locale;
pub mod weapon;
pub mod artifact;
pub mod locale;
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use anyhow::Context;
use mona::common::item_config_type::ItemConfig;
use mona::weapon::weapon_name::WeaponName;
use mona::weapon::weapon_static_data::WeaponStaticData;
Expand All @@ -17,7 +18,6 @@ struct WeaponMetaDataForJS {
configs: Vec<String>,
}


#[pyfunction]
pub fn gen_weapon_meta_as_json() -> PyResult<String> {
let mut data: Vec<WeaponMetaDataForJS> = Vec::new();
Expand Down Expand Up @@ -53,7 +53,6 @@ pub fn gen_weapon_meta_as_json() -> PyResult<String> {
data.push(my_data);
}


let result_str = serde_json::to_string(&data).unwrap();
let result_str = serde_json::to_string(&data).context("Failed to serialize json")?;
Ok(result_str)
}
}
2 changes: 1 addition & 1 deletion python_genshin_artifact_core/src/applications/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
pub mod generate;
pub mod wasm;
pub mod wasm;
12 changes: 8 additions & 4 deletions python_genshin_artifact_core/src/applications/wasm.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::JSONDecodeError;
use anyhow::Context;
use mona::artifacts::effect_config::{ArtifactConfigInterface, ArtifactEffectConfig};
use mona::artifacts::{Artifact, ArtifactList};
use mona::attribute::{AttributeUtils, ComplicatedAttributeGraph, SimpleAttributeGraph2};
Expand Down Expand Up @@ -64,7 +66,8 @@ impl From<TransformativeDamage> for TransformativeDamageBridge {

#[pyfunction]
pub fn get_damage_analysis(value_str: String) -> PyResult<String> {
let input: CalculatorConfigInterface = serde_json::from_str(&*value_str).unwrap();
let input: CalculatorConfigInterface = serde_json::from_str(&value_str)
.map_err(|e| JSONDecodeError::new_err((e.to_string(), value_str.to_owned(), 0)))?;

let character: Character<ComplicatedAttributeGraph> = input.character.to_character();
let weapon = input.weapon.to_weapon(&character);
Expand Down Expand Up @@ -96,14 +99,15 @@ pub fn get_damage_analysis(value_str: String) -> PyResult<String> {
None,
);

let result_str = serde_json::to_string(&result).unwrap();
let result_str = serde_json::to_string(&result).context("Failed to serialize json")?;
Ok(result_str)
}

#[pyfunction]
pub fn get_transformative_damage(value_str: String) -> PyResult<String> {
utils::set_panic_hook();
let input: CalculatorConfigInterface = serde_json::from_str(&*value_str).unwrap();
let input: CalculatorConfigInterface = serde_json::from_str(&value_str)
.map_err(|e| JSONDecodeError::new_err((e.to_string(), value_str.to_owned(), 0)))?;

let character: Character<SimpleAttributeGraph2> = input.character.to_character();
let weapon = input.weapon.to_weapon(&character);
Expand Down Expand Up @@ -140,6 +144,6 @@ pub fn get_transformative_damage(value_str: String) -> PyResult<String> {

let result = context.transformative();
let bridge = TransformativeDamageBridge::from(result);
let result_str = serde_json::to_string(&bridge).unwrap();
let result_str = serde_json::to_string(&bridge).context("Failed to serialize json")?;
Ok(result_str)
}
6 changes: 5 additions & 1 deletion python_genshin_artifact_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ use applications::generate::character::gen_character_meta_as_json;
use applications::generate::locale::gen_generate_locale_as_json;
use applications::generate::weapon::gen_weapon_meta_as_json;
use applications::wasm::{get_damage_analysis, get_transformative_damage};
use pyo3::import_exception;
use pyo3::prelude::*;

import_exception!(json, JSONDecodeError);

#[pymodule]
fn genshin_artifact_core(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
fn genshin_artifact_core(py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add("JSONDecodeError", py.get_type::<JSONDecodeError>())?;
m.add_function(wrap_pyfunction!(get_damage_analysis, m)?)?;
m.add_function(wrap_pyfunction!(get_transformative_damage, m)?)?;
m.add_function(wrap_pyfunction!(gen_character_meta_as_json, m)?)?;
Expand Down
Loading