usc 1.20230730.1349

A common lib for unitedservices
Documentation
use std::collections::HashMap;
use bevy_reflect::Reflect;
use crate::db::{BOOL_FALSE, BOOL_TRUE};
use crate::myerror::MyError;
use crate::{mylog, myok};

pub fn fields<T:bevy_reflect::Struct>(obj:&T) ->Result<Vec<String>,MyError> {
    let mut result =vec![];
    for (i, _value) in obj.iter_fields().enumerate() {
        let column_name = obj.name_at(i).unwrap();
        result.push (column_name.to_string());
    }
    Ok(result)
}

pub fn field_types<T:bevy_reflect::Struct>(obj:&T) ->Result<HashMap<String,String>,MyError> {
    let mut result :HashMap<String,String>=HashMap::new();
    for (i, value) in obj.iter_fields().enumerate() {
        let column_name = obj.name_at(i).unwrap();
        let column_type = value.type_name();
        result.insert(column_name.to_string(),column_type.to_string());
    }
    Ok(result)
}

pub fn fields_for_each<T:bevy_reflect::Struct,F>(obj:&T, f:F) ->Result<(),MyError> where F:FnOnce(&str,&dyn Reflect,&str) + std::marker::Copy   {
    for (i, value) in obj.iter_fields().enumerate() {
        let column_name = obj.name_at(i).unwrap();
        let column_type = value.type_name();
        f(column_name,obj.field_at(i).unwrap(),column_type);
    }
    Ok(())
}

pub fn get_field<'a,T:bevy_reflect::Struct,Q: bevy_reflect::Reflect>(obj:&'a T, field_name:& str) ->Result<&'a Q,MyError> {
    for (i, value) in obj.iter_fields().enumerate() {
        let column_name = obj.name_at(i).unwrap();
        if column_name!=field_name{
            continue
        }
        let _column_type = value.type_name();
        let column_val: &Q = obj.field_at(i).unwrap().downcast_ref::<Q>().unwrap();
        return Ok(column_val);
    }
    todo!()
}

pub fn get_field_string<T:bevy_reflect::Struct>(obj:&T, field_name:& str) ->Result<String,MyError> {
    for (i, value) in obj.iter_fields().enumerate() {
        let column_name = obj.name_at(i).unwrap();
        if column_name!=field_name{
            continue
        }
        let column_type = value.type_name();
        match column_type {
            "alloc::string::String" => {
                let column_val: String = obj
                    .field_at(i)
                    .unwrap()
                    .downcast_ref::<String>()
                    .unwrap()
                    .to_owned();
                return Ok(column_val);
            }
            "unitedservices::db::const_type_defaults::Bool" => {
                let column_val: &crate::db::Bool = obj
                    .field_at(i)
                    .unwrap()
                    .downcast_ref::<crate::db::Bool>()
                    .unwrap();
                match *column_val {
                    crate::db::Bool::True=>return Ok("1".to_owned()),
                    crate::db::Bool::Null=>return Ok("0".to_owned()),
                    crate::db::Bool::False=>return Ok("0".to_owned()),
                }
            }
            "i64" => {
                let column_val: i64 = *obj.field_at(i).unwrap().downcast_ref().unwrap();
                return Ok(format!("{column_val}"));
            }
            "f64" => {
                let column_val: f64 = *obj.field_at(i).unwrap().downcast_ref().unwrap();
                return Ok(format!("{column_val}"));
            }
            _ => {
                return Err(MyError::new(format!(
                    "mysql:first_mysql_model:column_type: Not Handled type {:?}",
                    column_type
                )));
            }
        }
    }
    todo!()
}

pub fn set_field<T:bevy_reflect::Struct,Q: bevy_reflect::Reflect>(obj:&mut T, field_name:& str,para:Q) ->Result<(),MyError> {
    let mut info = obj.clone_dynamic();
    for (i, _value) in obj.iter_fields().enumerate() {
        let name = obj.name_at(i).unwrap();
        if name!=field_name{
            continue
        }
        info.insert(name, para);
        break;
    }
    obj.apply(&info);
    Ok(())
}

pub fn set_field_by_str<T:bevy_reflect::Struct+ ?Sized>(obj:&mut T, field_name:& str,para:&str) ->Result<(),MyError> {
    let mut info = obj.clone_dynamic();
    for (i, value) in obj.iter_fields().enumerate() {
        let name = obj.name_at(i).unwrap();
        if name!=field_name{
            continue
        }
        let para_string=para.to_string();
        match value.type_name() {
            "alloc::string::String" => {
                info.insert(name,para_string );
            }
            "i32" => {
                info.insert(name, myok!(para_string.parse::<i32>(),?));
            }
            "i64" => {
                info.insert(name, myok!(para_string.parse::<i64>(),?));
            }
            "f32" => {
                info.insert(name, myok!(para_string.parse::<f32>(),?));
            }
            "f64" => {
                info.insert(name, myok!(para_string.parse::<f64>(),?));
            }
            "unitedservices::db::const_type_defaults::Bool"=>{
                match para{
                    "1"|"TRUE"|"True"|"Yes"|"YES"|"true"|"yes"=>{
                        info.insert(name, BOOL_TRUE);
                    }
                    _=>{
                        info.insert(name, BOOL_FALSE);
                    }
                }
            }
            &_ => {
                mylog!("value.type_name()",value.type_name());
                return Err(MyError::new(format!("set_field_by_str fail,invaid type name :{}",value.type_name())));
            },
        }
    }
    obj.apply(&info);
    Ok(())
}