#![doc = include_str!("readme.md")]
use crate::instructions::PythonInstruction;
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum PythonVersion {
#[default]
Unknown,
Python3_7,
Python3_8,
Python3_9,
Python3_10,
Python3_11,
Python3_12,
Python3_13,
Python3_14,
}
impl PythonVersion {
pub fn from_magic(magic: [u8; 4]) -> Self {
match magic {
[66, 13, 13, 10] => PythonVersion::Python3_7,
[85, 13, 13, 10] => PythonVersion::Python3_8,
[97, 13, 13, 10] => PythonVersion::Python3_9,
[112, 13, 13, 10] => PythonVersion::Python3_10,
[168, 13, 13, 10] => PythonVersion::Python3_11,
[203, 13, 13, 10] => PythonVersion::Python3_12,
[243, 13, 13, 10] => PythonVersion::Python3_13,
[43, 14, 13, 10] => PythonVersion::Python3_14,
_ => PythonVersion::Unknown,
}
}
pub fn as_magic(&self) -> [u8; 4] {
match self {
PythonVersion::Python3_7 => [66, 13, 13, 10],
PythonVersion::Python3_8 => [85, 13, 13, 10],
PythonVersion::Python3_9 => [97, 13, 13, 10],
PythonVersion::Python3_10 => [112, 13, 13, 10],
PythonVersion::Python3_11 => [168, 13, 13, 10],
PythonVersion::Python3_12 => [203, 13, 13, 10],
PythonVersion::Python3_13 => [243, 13, 13, 10],
PythonVersion::Python3_14 => [43, 14, 13, 10],
PythonVersion::Unknown => [0, 0, 0, 0],
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct PycHeader {
pub magic: [u8; 4],
pub flags: u32,
pub timestamp: u32,
pub size: u32,
}
impl Default for PycHeader {
fn default() -> Self {
Self { magic: [0; 4], flags: 0, timestamp: 0, size: 0 }
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Upvalue {
pub in_stack: u8,
pub idx: u8,
pub name: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct LocalVar {
pub name: String,
pub start_pc: u32,
pub end_pc: u32,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub enum PythonObject {
Str(String),
Int(i32),
Integer(i64),
Float(f64),
Bool(bool),
String(String),
List(Vec<PythonObject>),
Tuple(Vec<PythonObject>),
Bytes(Vec<u8>),
Code(PythonCodeObject),
#[default]
None,
}
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
pub struct PythonCodeObject {
pub name: String,
pub qualname: String,
pub source_name: String,
pub first_line: u32,
pub last_line: u32,
pub co_argcount: u8,
pub co_posonlyargcount: u8,
pub co_kwonlyargcount: u8,
pub co_nlocals: u8,
pub co_stacksize: u8,
pub co_flags: u32,
pub co_code: Vec<PythonInstruction>,
pub co_consts: Vec<PythonObject>,
pub co_names: Vec<String>,
pub co_localsplusnames: Vec<String>,
pub co_localspluskinds: Vec<u8>,
pub co_linetable: Vec<u8>,
pub co_exceptiontable: Vec<u8>,
}
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
pub struct PythonProgram {
pub header: PycHeader,
pub code_object: PythonCodeObject,
pub version: PythonVersion,
}