You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: freight_station.rs
    path of file: ./repos/Egregoria/simulation/src/souls
    
    the code of the file until where you have to start completion: use serde::{Deserialize, Serialize};

use geom::Transform;
use prototypes::{FreightStationPrototypeID, GameTime};

use crate::map::{BuildingID, Map, PathKind};
use crate::map_dynamic::{
    BuildingInfos, D
    
pub fn freight_station_system(world: &mut World, resources: &mut Resources) {
    profiling::scope!("souls::freight_station_system");
    let cbuf = resources.read::<ParCommandBuffer<FreightStationEnt>>();
    let mut dispatch = resources.write::<Dispatcher>();
    let map = resources.read::<Map>();
    let time = resources.read::<GameTime>();
    let tick = time.tick;

    for (me, f) in world.freight_stations.iter_mut() {
        let pos = f.trans;
        let station = &mut f.f;
        if !map.buildings.contains_key(station.building) {
            cbuf.kill(me);
            continue;
        }

        // update our trains, and remove the ones that are done
        let mut to_clean = vec![];
        for (trainid, state) in &mut station.trains {
            let Some(train) = world.trains.get_mut(*trainid) else {
                to_clean.push(*trainid);
                continue;
            };
            let itin = &mut train.it;

            match state {
                FreightTrainState::Arriving => {
                    if itin.has_ended(0.0) {
                        *state = FreightTrainState::Loading;
                        station.waiting_cargo = station.waiting_cargo.saturating_sub(100);
                        station.wanted_cargo = station.wanted_cargo.saturating_sub(100);
                        *itin = Itinerary::wait_until(time.timestamp + 10.0);
                    }
                }
                FreightTrainState::Loading => {
                    if itin.has_ended(time.timestamp) {
                        let ext = *map.external_train_stations.first().unwrap();
                        let bpos = map.buildings[ext].obb.center().z(0.0);

                        *itin = if let Some(r) =
                            Itinerary::route(tick, train.trans.pos, bpos, &map, PathKind::Rail)
                        {
                            r
                        } else {
                            Itinerary::wait_until(time.timestamp + 10.0);
                            continue;
                        };
                        *state = FreightTrainState::Moving;
                    }
                }
                FreightTrainState::Moving => {
                    if itin.has_ended(time.timestamp) {
                        to_clean.push(*trainid);
                    }
                }
            }
        }
        for v in to_clean {
            station.trains.retain(|x| x.0 != v);
            dispatch.free(v)
        }

        // If enough goods are waiting, query for a train to take them to the external trading station
        if station.trains.len() >= MAX_TRAINS_PER_STATION {
            continue;
        }
        if station.waiting_cargo + station.wanted_cargo < 10 {
            continue;
        }

        let destination = pos.pos + pos.dir * 75.0 - pos.dir.perp_up() * 40.0;

        let Some(DispatchID::FreightTrain(trainid)) = dispatch.query(
            &map,
            DispatchKind::FreightTrain,
            DispatchQueryTarget::Pos(destination),
        ) else {
            continue;
        };

        let train = world.trains.get_mut(trainid).unwrap();

        train.it = unwrap_or!(
            Itinerary::route(tick, train.trans.pos, destination, &map, PathKind::Rail,),
            continue
        );

        station.trains.push((trainid, FreightTrainState::Arriving));
    }
}